SvelteKit and Tailwind / Windi CSS

  • Sascha Aeppli

My setup with SvelteKit and Tailwind. Thanks to Windi CSS and its Vite plugin, it's very fast and simple to set up.

TL;DR

Check out this repo: github.com/munxar/sveltekit-tailwind
thanks and goodbye :-)

Setup SvelteKit

mkdir myproject
cd myproject
npm init svelte@next

Note: I choose TypeScript and only CSS when asked by the wizard, but you can choose whatever you like.

Install Windi CSS

Because SvelteKit now uses Vite 2 as a preprocessor in development mode, we use vite-plugin-windicss.

npm i -D vite-plugin-windicss

Now I import the plugin int the svelte.config.cjs file:

// svelte.config.cjs
const sveltePreprocess = require('svelte-preprocess');
const node = require('@sveltejs/adapter-node');
const pkg = require('./package.json');
const WindiCSS = require('vite-plugin-windicss').default

/** @type {import('@sveltejs/kit').Config} */
module.exports = {
    // Consult https://github.com/sveltejs/svelte-preprocess
    // for more information about preprocessors
    preprocess: sveltePreprocess(),         
    kit: {
        // By default, `npm run build` will create a standard Node app.
        // You can create optimized builds for different platforms by
        // specifying a different adapter
        adapter: node(),

        // hydrate the <div id="svelte"> element in src/app.html
        target: '#svelte',

        vite: {
            ssr: {
                noExternal: Object.keys(pkg.dependencies || {})
            },
            plugins: [
                WindiCSS(),
            ]
        }
    }
};

Very basic stuff, import the plugin and add it to the vite plugins section.
Because the Windi CSS plugin is written as ES Module (ESM) and this file is a Common JS module (CJS), I need to add the ".default" to make it work.

Enable Windi CSS

Open the src/routes/$layout.svelte file and add this import:

<!-- src/routes/$layout.svelte -->
<script>
    import 'virtual:windi.css';
</script>

Enable Developer Tools integration (optional)

Sometimes I like to tinker in the developer tools of the browser while prototyping. This can be done with this optional import.

<!-- src/routes/$layout.svelte -->
<script>
    import { onMount } from 'svelte';
    import 'virtual:windi.css'; 
    onMount(() => {
        import('virtual:windi-devtools');
    });
</script>

<slot />

By putting the import('virtual:windi-devtools') into the onMount callback, we delay the loading when the client is running in a real browser environment and not while server-side rendering.

Add Tailwind Plugins / Config

I need to add some settings, so I use my plain old tailwind config file. There are two important details:

  1. The file must be named tailwind.config.cjs (not .js)
  2. If you need plugins, import them from windicss/plugin
    Here is my example config:
// tailwind.config.cjs

module.exports = {
    dark: 'class',
    plugins: [
        require('windicss/plugin/forms'),
        require('windicss/plugin/aspect-ratio'),
        require('windicss/plugin/line-clamp'),
        require('windicss/plugin/filters'),
        require('windicss/plugin/scroll-snap'),     
    ],
}

Done. Really? Yes!
We have all set up to use what Tailwind offers and much more. Check out the Windi CSS documentation for the amazing details.
I use VS Code as an editor and love the Windi CSS plugin, check it out: WindiCSS IntelliSense

Recap

This is everything I had to do. Imho Windi CSS has some very nice advantages over plain Tailwindcss (even the @tailwindcss/jit).
If you have some questions or inputs drop a comment.
Build some amazing web applications!


Tell us what you think