Using Windi CSS in Svelte

svelte-windicss-preprocess provides simple integration for Windi CSS in Svelte and Sapper.

Now we have a great playground, you can try it online before installing it.

Installation 💿

Add the package:

npm install svelte-windicss-preprocess --save-dev

Migrating

If migrating from Tailwind CSS, also check out the Migration section

Configuration ⚙️

Add svelte-windicss-preprocess to your Rollup or Webpack configuration.

If using:

Vanilla Svelte

Add svelte-windicss-preprocess to your rollup.config.js.

Typescript is optional. Include sveltePreprocess.typescript() into preprocess if you are using typescript in your Svelte component.

// rollup.config.js
import sveltePreprocess from "svelte-preprocess";
// ...
export default {
  // ...
  plugins: [
    svelte({
      // svelte-windicss-preprocess
      preprocess: [
        sveltePreprocess.typescript(), // to support typescript (optional)
        require('svelte-windicss-preprocess').preprocess({
          config: 'tailwind.config.js', // tailwind config file path (optional)
          compile: true, // false: interpretation mode; true: compilation mode
          prefix: 'windi-', // set compilation mode style prefix
          globalPreflight: true, // set preflight style is global or scoped
          globalUtility: true, // set utility style is global or scoped
        })
      ],
      // ...
    }),
  ],
  // ...
};

Sveltekit

Add the [vite-plugin-windicss] package:

npm install vite-plugin-windicss --save-dev

Then, add the plugin to your Vite configuration in svelte.config.cjs:

// svelte.config.cjs
const node = require('@sveltejs/adapter-node');
const pkg = require('./package.json');

/** @type {import('@sveltejs/kit').Config} */
module.exports = {
  kit: {
    adapter: node(),

    target: '#svelte',

    vite: {
      ssr: {
        noExternal: Object.keys(pkg.dependencies || {})
      },
      plugins: [
        require('vite-plugin-windicss').default()
      ]
    }
  }
};

And finally, import windi.css in your main layout:

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

<slot></slot>

Sapper(rollup)

Add svelte-windicss-preprocess to your rollup.config.js.

// rollup.config.js
// ...
export default {
  // ...
  client: {
    input: config.client.input(),
    output: config.client.output(),
    plugins: [
      // ...
      svelte({
        // svelte-windicss-preprocess
        preprocess: require('svelte-windicss-preprocess').preprocess({
          config: 'tailwind.config.js',     // tailwind config file path
          compile: true,                    // false: interpretation mode; true: compilation mode
          prefix: 'windi-',                 // set compilation mode style prefix
          globalPreflight: true,            // set preflight style is global or scoped
          globalUtility: true,              // set utility style is global or scoped
        }),
        compilerOptions: {
          // ...
        }
      }),
      // ...
    ]
  // ...
  }
  server: {
    input: config.server.input(),
    output: config.server.output(),
    plugins: [
      // ...
      svelte({
        // svelte-windicss-preprocess
        preprocess: require('svelte-windicss-preprocess').preprocess({
          config: 'tailwind.config.js',      // tailwind config file path
          compile: true,                     // false: interpretation mode; true: compilation mode
          prefix: 'windi-',                  // set compilation mode style prefix
          globalPreflight: true,             // set preflight style is global or scoped
          globalUtility: true,               // set utility style is global or scoped
        }),
        compilerOptions: {
          // ...
        },
      }),
      // ...
    ]
  }
  // ...
}

Sapper(webpack)

Add svelte-windicss-preprocess to your webpack.config.js.

// webpack.config.js
module.exports = {
  client: {
    // ...
    module: {
      rules: [
        {
          test: /\.(svelte|html)$/,
          use: {
            loader: 'svelte-loader',
            options: {
              // ... other options
              // svelte-windicss-preprocess
              preprocess: require('svelte-windicss-preprocess').preprocess({
                config: 'tailwind.config.js',    // tailwind config file path
                compile: true,                   // false: interpretation mode; true: compilation mode
                prefix: 'windi-',                // set compilation mode style prefix
                globalPreflight: true,           // set preflight style is global or scoped
                globalUtility: true,             // set utility style is global or scoped
              })
            }
          }
        },
        // ...
      ]
    },
  },

  server: {
    // ...
    module: {
      rules: [
        {
          test: /\.(svelte|html)$/,
          use: {
            loader: 'svelte-loader',
            options: {
              // ... other options
              // svelte-windicss-preprocess
              preprocess: require('svelte-windicss-preprocess').preprocess({
                config: 'tailwind.config.js',     // tailwind config file path
                compile: true,                    // false: interpretation mode; true: compilation mode
                prefix: 'windi-',                 // set compilation mode style prefix
                globalPreflight: true,            // set preflight style is global or scoped
                globalUtility: true,              // set utility style is global or scoped
              })
            }
          }
        },
        // ...
      ]
    },
  }
}

Setup VSCode Extension

If you are using Svelte for VS Code vscode extension, I believe most people are using it. You will need to add "vetur.validation.style": false to your configuration file.

Hit ctrl-shift-p or cmd-shift-p on mac, type open settings, and select Preferences: Open Settings (JSON). Add "vetur.validation.style": false to settings.json then save it.

Then you will need to tell svelte-vscode to restart the svelte language server in order to pick up a new configuration.

Hit ctrl-shift-p or cmd-shift-p on mac, type svelte restart, and select Svelte: Restart Language Server. Any errors you were seeing should now go away and you're now all set up!

Additional Features in Svelte ⚡️

svelte-windicss-preprocess also supports the following features:

Variant Attributes

You can apply several utilities for the same variant by using HTML attributes.

<div w:sm="bg-white font-bold" w:hover="bg-gray-200" w:dark="bg-gray-900"/>

Mixed Variants

Variants, such as sm:hover, are not supported inside attributes. Use utility groups instead.