Tailwind v4 — The Biggest Rewrite in Its History
Tailwind CSS v4, released in early 2025 and now the standard for new projects in 2026, is a complete rewrite from the ground up. The utility classes you know and love are unchanged — flex, p-4, text-lg, bg-blue-500 all work exactly the same. But the engine underneath, the configuration system, and the theming approach are entirely new.
The headline improvements: 5-10x faster builds, zero JavaScript configuration, better colors, and a simpler mental model. Let's break down every change that matters.
1. CSS-First Configuration
The tailwind.config.js file is gone. All configuration now lives in your CSS file using the @theme directive. This is the most significant change and the one that simplifies everything else:
/* app.css */
@import "tailwindcss";
@theme {
/* Colors */
--color-primary: oklch(55% 0.25 270);
--color-secondary: oklch(60% 0.2 300);
--color-accent: oklch(70% 0.18 150);
--color-bg-primary: oklch(8% 0.01 270);
--color-bg-secondary: oklch(12% 0.01 270);
--color-text-primary: oklch(98% 0 0);
--color-text-secondary: oklch(70% 0.01 270);
/* Typography */
--font-sans: "Inter", system-ui, sans-serif;
--font-mono: "JetBrains Mono", monospace;
--font-display: "Space Grotesk", system-ui, sans-serif;
/* Spacing */
--spacing-18: 4.5rem;
--spacing-88: 22rem;
/* Breakpoints */
--breakpoint-3xl: 120rem;
/* Animations */
--animate-fade-in: fade-in 0.5s ease-out;
--animate-slide-up: slide-up 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slide-up {
from { transform: translateY(20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
Every CSS custom property you define in @theme automatically becomes a Tailwind utility. The above configuration gives you:
bg-primary,text-secondary,border-accent— all your custom colorsfont-sans,font-mono,font-display— font family utilitiesmt-18,w-88— custom spacing values3xl:— custom breakpoint prefixanimate-fade-in,animate-slide-up— custom animations
No build step for configuration. No JavaScript file to import and parse. Pure CSS. This also means your configuration is visible in browser DevTools — you can inspect --color-primary directly.
2. Lightning CSS Engine
Tailwind v4 replaces PostCSS with Lightning CSS, a Rust-powered CSS processor built by the Parcel team. The performance difference is dramatic:
| Metric | Tailwind v3 (PostCSS) | Tailwind v4 (Lightning CSS) |
|---|---|---|
| Initial build | ~800ms | ~100ms |
| Incremental rebuild | ~200ms | ~15ms |
| Production minification | ~400ms | ~50ms |
Lightning CSS also handles vendor prefixing, CSS nesting, and modern syntax transforms — all in one pass. You no longer need autoprefixer as a separate PostCSS plugin.
3. OKLCH Color Space
Tailwind v4's default color palette uses OKLCH (Oklab Lightness Chroma Hue) instead of HSL or hex. Why this matters:
- Perceptual uniformity: Two colors with the same lightness value actually look equally bright. In HSL, yellow at 50% lightness appears much brighter than blue at 50% lightness.
- P3 wide gamut: OKLCH can represent colors outside the sRGB gamut, taking advantage of modern P3-capable displays (which includes most phones and laptops made after 2020).
- Better opacity mixing:
bg-primary/50produces more natural-looking transparent overlays in OKLCH.
/* OKLCH format: oklch(lightness chroma hue) */
--color-indigo-500: oklch(55% 0.25 270); /* vibrant on P3, graceful fallback on sRGB */
--color-purple-500: oklch(55% 0.23 300);
--color-green-500: oklch(65% 0.2 150);
4. Automatic Content Detection
Tailwind v4 automatically detects which files to scan for class names — no more content: ["./src/**/*.{ts,tsx}"] in the config. It uses your project's file structure and import graph to figure this out. One less thing to configure.
5. Native CSS Nesting
Since Tailwind v4 uses Lightning CSS, native CSS nesting works out of the box:
.card {
background: var(--color-bg-secondary);
border-radius: 1rem;
&:hover {
transform: translateY(-2px);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}
& .title {
font-weight: 700;
color: var(--color-text-primary);
}
}
6. Simplified Dark Mode
Dark mode variants use the same CSS custom properties, toggled by the standard prefers-color-scheme media query or a class strategy:
@theme {
--color-bg: white;
--color-text: black;
}
@theme dark {
--color-bg: oklch(8% 0.01 270);
--color-text: oklch(98% 0 0);
}
Migration from v3
Tailwind provides an official codemod that handles most breaking changes automatically:
# Run the official migration tool
npx @tailwindcss/upgrade@latest
What the codemod handles:
- Converts
tailwind.config.jstheme values to@themeCSS variables - Renames deprecated utilities (
overflow-ellipsis→text-ellipsis, etc.) - Updates PostCSS config to remove Tailwind-specific plugins
What you'll need to handle manually:
- Custom plugins using the old JS API — rewrite with CSS or the new v4 plugin API
- Theme values accessed in JavaScript (e.g., via
resolveConfig) — switch to CSS custom properties withgetComputedStyle - PostCSS plugins that depend on Tailwind's PostCSS pipeline — some may need alternatives
Should You Upgrade?
- New projects: Start with v4. No question.
- Existing v3 projects (small-medium): The codemod makes migration low-risk. Build speed improvement alone justifies it.
- Large v3 projects with custom plugins: Plan a migration sprint. Test the codemod on a branch first. The benefits are real but the plugin migration may take effort.
We design and build responsive, accessible interfaces with the latest CSS technology. Let's talk →