Svelte, PostCSS and TypeScript with Svite bundler

· 4 min

Svite has been on my radar for quite some time now and I finally found some time to play with it. I was surprised by the results.

I am on the quest to find the easiest, fastest and most flexible bundler for Svelte development. I think I just did.

My requirementspermalink

Testing different Svelte bundler setups is a weird hobby of mine. I get a kick out of connecting different plugins together, while trying to setup a smooth development workflow.

The requirements are pretty straight forward.

  • It must be fast
  • It must support Typescript
  • It must support PostCSS
  • It must produce small and efficient bundles
  • It must produce correct sourcemaps for debugging
  • It should support HMR (Hot Module Replacement)

My testing applicationpermalink

For my tests I created a simple Svelte app. Its functionality is simple. You press a button and it fetches a random Kanye West tweet from Kanye as a Service.

Kanye Says app screenshot

While simple, the application has some interesting parts.

  • Svelte components are written in Typescript. I want to see if transpiling and type checking works correctly for TS.
  • External Svelte library. Not all bundlers support libraries written in Svelte efficiently.
  • External library dependency. I want to see if a bundler supports tree shaking when bundling for production.
  • Extenral Assets. It should be possible to import SVG, PNG, JSON and other external assets in our code.
  • PostCSS with TailwindCSS. A good bundler should make it easy to work with SASS and PostCSS.
  • Business components in Typescript. Typescript is here to stay. A good bundler should support it out-of-the-box.

Can Svite handle the pressure? Let's see!

Short notes on Svitepermalink

Svite is a pure Svelte bundler built by dominikg on top of Vite. I've already tested Vite with very impressive results, and since Svite is almost Vite, I expect the results to be equal or better.

What's great about Svite is that it has many different templates you can use when creating your app. Currently there are four:

  • minimal
  • routify-mdsvex
  • postcss-tailwind
  • svelte-preprocess-auto

It has also a few other useful options you can use too.

Creating a new projectpermalink

Let's create an app by using postcss-tailwind template and adding TypeScript support.

$ npx svite create -pm pnpm -ts -t postcss-tailwind -sc svelte-svite-typescript
$ cd svelte-svite-typescript
$ npm run dev

That was easy! Let's look at the files it produced.

$ ls -1
index.html
node_modules
package.json
pnpm-lock.yaml
postcss.config.js
public
src
svelte.config.js
tailwind.config.js
tsconfig.json

And in the src directory you have these files.

$ ls src
App.svelte index.css index.ts

Nice! Almost the same files I had to write by hand when testing Vite.

Why almost? If you worked with Vite, you might notice that there is no vite.config.js. Because Svite has build in support for Svelte, there is no need to have one.

App.svelte

The file is small and with helpful comments in the right places.

<script lang="ts">
const world = 'postcss'; // edit world and save to see hmr update
</script>

<style>

h1 {
color: orangered; /* change color an save to see hmr update */
/* you can also use css nesting
& .world {
font-size: 2rem;
}
*/

}
.world {
@apply text-teal-500 italic; /* here's some tailwind apply */
}
</style>

<h1 class="border border-current rounded p-4 m-4">
<!-- tailwind classes in svelte template -->
Hello
<span class="world">
{world}</span>
</h1>

index.ts

The main file is clean and imports our base Tailwind file.

import App from './App.svelte';
import './index.css';

const app = new App({
target: document.body,
});

export default app;

package.json

The package.json is clean and small.

{
"name": "svelte-svite-typescript",
"version": "0.0.0",
"scripts": {
"validate": "svelte-check && tsc --noEmit",
"dev": "svite -ts",
"build": "svite build -ts"
},
"dependencies": {
"svelte": "3.24.1",
"svelte-hmr": "0.10.2"
},
"devDependencies": {
"@tsconfig/svelte": "^1.0.10",
"postcss": "^7.0.32",
"postcss-import": "^12.0.1",
"postcss-load-config": "^2.1.0",
"postcss-preset-env": "^6.7.0",
"svelte-check": "^1.0.21",
"svelte-preprocess": "4.1.1",
"svite": "^0.6.0",
"tailwindcss": "^1.7.3",
"tslib": "^2.0.1",
"typescript": "^3.9.7"
}
}

A few dependencies are outdated, but we can update them with ncu -u && pnpm install command.

When starting everything works as advertised. Impressive!

Testing with Svite with my benchmark apppermalink

I copied the files in src directory from my Vite test setup and the app worked out of the box! I am not surprised since Svite is Vite abstracted.

Buildingpermalink

Let's compare Svite builds to Vite's.

# Svite

[write] dist/_assets/index.ab6f11f2.js 32.04kb, brotli: 9.50kb
[write] dist/_assets/style.45ed9e6c.css 8.10kb, brotli: 1.81kb
[write] dist/_assets/usa.fcca7834.svg 0.88kb
[write] dist/index.html 0.40kb, brotli: 0.16kb
Build completed in 8.37s.

# Vite

[write] dist/_assets/index.0729edbe.js 32.04kb, brotli: 9.50kb
[write] dist/_assets/style.393fa0c4.css 6.39kb, brotli: 1.67kb
[write] dist/_assets/usa.6aae1c82.svg 0.88kb
[write] dist/index.html 0.41kb, brotli: 0.16kb
Build completed in 5.16s.

The results are almost identical in terms of output and speed.

Resultspermalink

Let's re-visit our list of requirements.

  • It must be fast. Check. Vite's cold starts and reloads feel superfast.
  • It must support Typescript. Check. Works out-of-the-box.
  • It must support PostCSS. Check. Works out-of-the-box.
  • It must produce small and efficient bundles. Check. Rollup is used for bundling.
  • It should be possible to import external Svelte libs. Check.
  • It must produce correct sourcemaps for debugging. So-so. Not very impressed, but ok.
  • It should support HMR (Hot Module Replacement). Check. Works great.

One annoying thing I found is that when you kill the dev server the whole app starts reloading itself.

Plugins and Libraries Mentionedpermalink

Conclusionpermalink

Svite is a nice little abstraction of Vitejs specifically tailored for Svelte development. It's fast, small and doesn't get in your way. Everything just works.

It feels thought though. For example, one thing I like is that Svite allows you to choose which package manager you want to use. It might be a small thing, but it's really nice that the author has thought of this.

If you feel you need to use some other Vite plugins that Svite doesn't offer, you can always create vite.config.js and wire them up there.

I didn't bother to setting up other useful scripts this time, like continuous linting, but if you are interested check out package.json in my Vite setup in the Github repo.

Svite might just be the easiest way to get your new Svelte project off the ground. The documentation is excellent and you have many different boilerplate templates to choose from. Just make sure to read the docs for all the possible options!

You can find the code here https://github.com/codechips/svelte-typescript-setups

I will definitely use Svite in the future!


If you liked what you read, it would make me really happy if you could share it on Twitter.