Using Windi CSS in Vite.js
Features
- ⚡️ It's FAST - 20~100x times faster than Tailwind on Vite
- 🧩 On-demand CSS utilities
- 📦 On-demand native elements style reseting
- 🔥 Hot module replacement (HMR)
- 🍃 Load configurations from
tailwind.config.js
- 🤝 Framework-agnostic - Vue, React, Svelte and vanilla!
- 📄 CSS
@apply
/@screen
directives transforms (also works for Vue SFC's<style>
) - 🎳 Support Utility Groups - e.g.
bg-gray-200 hover:(bg-gray-100 text-red-300)
Check out the speed comparison between Windi CSS and Tailwind CSS on Vite.
Install
Install the package:
npm install vite-plugin-windicss --save-dev
Then, install the plugin in your Vite configuration:
// vite.config.js
import WindiCSS from 'vite-plugin-windicss'
export default {
plugins: [
WindiCSS(),
],
}
And finally, import virtual:windi.css
in your Vite entries:
// main.js
import 'virtual:windi.css'
That's it! Starting using classes utilities or CSS directives in your app, and enjoy the speed! ⚡️
If you are migrating from Tailwind CSS, also check out the Migration section
Supports
TypeScript
Enable TypeScript for your tailwind.config.js
? Sure, why not?
Rename it to tailwind.config.ts
and things will just work!
// tailwind.config.ts
import { defineConfig } from 'windcss/helpers'
import formsPlugin from 'windicss/plugin/forms'
export default defineConfig({
darkMode: 'class',
safelist: 'p-3 p-4 p-5',
theme: {
extend: {
colors: {
teal: {
100: '#096',
},
},
},
},
plugins: [formsPlugin],
})
Pug Support
It will automatically enable Pug support for .pug
and Vue SFC when dependency pug
is found in the workspace.
"Design in DevTools"
⚗️ Experimental
It might be a common practice when you use the purge-based Tailwind where you have all the classes in your browser and you can try how things work by directly changing the classes in DevTools. While you might think this is some kind of limitation of "on-demand" where the DevTools don't know those you haven't used in your source code yet.
But unfortunately, we are here to BREAK the limitation 😎 See the video demo.
Just add the following line to your main entry
import 'virtual:windi-devtools'
It will be enabled automatically for you, have fun!
Oh and don't worry about the final bundle, in production build virtual:windi-devtools
will be an empty module and you don't have to do anything about it 😃
⚠️ Please use it with caution, under the hood we use MutationObserver to detect the class changes. Which means not only your manual changes but also the changes made by your scripts will be detected and included in the stylesheet. This could cause some misalignment between dev and the production build when using dynamically constructed classes (false-positive). We recommended adding your dynamic parts to the
safelist
or setup UI regression tests for your production build if possible.
Configuration
Preflight (style reseting)
Preflight is enables on demanded, if you'd like to completely disable it, you can configure it as below
// windi.config.ts
import { defineConfig } from 'vite-plugin-windicss'
export default defineConfig({
preflight: false,
})
Safelist
By default, we scan your source code statically and find all the usages of the utilities then generated corresponding CSS on-demand. However, there is some limitation that utilities that decided in the runtime can not be matched efficiently, for example
<!-- will not be detected -->
<div className={`p-${size}`}>
For that, you will need to specify the possible combinations in the safelist
options of vite.config.js
.
// windi.config.ts
import { defineConfig } from 'vite-plugin-windicss'
export default defineConfig({
safelist: 'p-1 p-2 p-3 p-4',
})
Or you can do it this way
// windi.config.ts
import { defineConfig } from 'vite-plugin-windicss'
function range(size, startAt = 1) {
return Array.from(Array(size).keys()).map(i => i + startAt)
}
export default defineConfig({
safelist: [
range(30).map(i => `p-${i}`), // p-1 to p-3
range(10).map(i => `mt-${i}`), // mt-1 to mt-10
],
})
Scanning
On server start, vite-plugin-windicss
will scan your source code and extract the utilities usages. By default, only files under src/
with extensions vue, html, mdx, pug, jsx, tsx
will be included. If you want to enable scaning for other file type of locations, you can configure it via:
// windi.config.js
import { defineConfig } from 'windcss/helpers'
export default defineConfig({
extract: {
include: ['src/**/*.{vue,html,jsx,tsx}'],
exclude: ['node_modules', '.git'],
},
})
Or in plugin options:
// vite.config.js
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
WindiCSS({
scan: {
dirs: ['.'], // all files in the cwd
fileExtensions: ['vue', 'js', 'ts'], // also enabled scanning for js/ts
},
}),
],
})
More
See options.ts for more configuration reference.
Caveats
Scoped Style
You will need to set transformCSS: 'pre'
to get Scoped Style work.
@media
directive with scoped style can only works with css
postcss
scss
but not sass
, less
nor stylus
Example
See examples for react, vue and vue with pug sample projects, or Vitesse