Tailwind v4 landed in early 2025 and it’s not an incremental release. The engine was rewritten from scratch, the configuration model changed completely, and the integration method shifted. If you’ve been on v3 for a while, here’s what you actually need to know.
The engine: Oxide
v4 replaces the JavaScript parser with Oxide — a Rust-based engine. In practice:
- Full builds are ~5x faster
- Incremental builds are much faster still — Oxide only processes changed files
- No more PostCSS dependency for most setups
The performance improvement is noticeable in large projects. On this site (small) the difference is milliseconds. On a design system with hundreds of components, it matters.
Configuration: from JS to CSS
The biggest conceptual change. In v3, you configured Tailwind in tailwind.config.js. In v4, configuration moves into your CSS file:
v3:
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
accent: '#2f636a',
},
},
},
};
v4:
/* global.css */
@import 'tailwindcss';
@theme {
--color-accent: #2f636a;
}
The @theme block defines CSS custom properties that Tailwind uses to generate utilities. You get both Tailwind classes (text-accent) and raw CSS variables (var(--color-accent)) automatically.
Integration: no more @astrojs/tailwind
The @astrojs/tailwind Astro integration only supports Tailwind v3. For v4, you skip the integration entirely and use the Vite plugin directly:
// astro.config.mjs
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
vite: {
plugins: [tailwindcss()],
},
});
That’s it. No tailwind.config.js, no PostCSS config. Just the Vite plugin and your CSS file.
What broke
@apply with v3 utilities
Some v3 utility names changed in v4. If you used @apply extensively, you’ll have compilation errors. The migration guide covers the renamed utilities.
JIT is now always-on
In v3, JIT was optional. In v4 it’s the only mode. No config needed, but if you were relying on pre-generated CSS (unlikely, but possible), you’ll need to adjust.
Peer dependencies
@tailwindcss/vite requires Vite 5+. @tailwindcss/postcss is separate if you still need PostCSS. Don’t install tailwindcss and @tailwindcss/vite together without reading the docs — the package structure changed.
Worth it?
Yes. The CSS-first configuration model is more intuitive once you get past the initial adjustment. Your design tokens live in CSS, not JavaScript, which means:
- You can use them with
var()anywhere — not just via Tailwind classes - Your IDE gives you CSS autocomplete on the variables
- You can override tokens per-component without JS config changes
The performance gain alone isn’t a reason to migrate a working project. The config model change is.