Svelte, PostCSS and TypeScript with Svite bundler
Tags: svelte, webdev, typescript, javascript
Published: 2020-11-27 09:05:37

---
title: Svelte, PostCSS and TypeScript with Svite bundler
published: true
date: 2020-09-06 00:00:00 UTC
tags: svelte, webdev, typescript, javascript
canonical_url: https://codechips.me/svelte-postcss-and-typescript-with-svite/
---

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 requirements

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 application

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](https://kanye.rest/).

![Kanye Says app screenshot](https://res.cloudinary.com/codechips/image/upload/v1598252607/kanye-says-app_rup4n6.webp)

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.
- **External 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](https://github.com/dominikg/svite) handle the pressure? Let's see!

## Short notes on Svite

[Svite](https://github.com/dominikg/svite) is a pure Svelte bundler built by [dominikg](https://github.com/dominikg) on top of [Vite](https://github.com/vitejs/). I've already tested Vite with very [impressive results](/svelte-with-vitejs-typescript-tailwind/), 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 project

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

```text
$ 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.

```text
$ 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.


```text
$ 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.

```html
<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.

```ts
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.

```json
{
  "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 app

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.

## Building

Let's compare Svite builds to Vite's.

```text
# 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.

## Results

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 Mentioned

- https://github.com/dominikg/svite
- https://github.com/vitejs/vite

## Conclusion

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!