The Complete Guide to Tailwind CSS v4
Tailwind v4 rewrites the engine in Rust, moves configuration into CSS, and drops PostCSS as a requirement. Here's everything you need to know to migrate and get the most out of it.

Tailwind CSS v4 is not an incremental upgrade, it's a ground-up rewrite. A new Rust-based compiler (Oxide), CSS-native configuration, native container queries, and a dramatically simplified setup make it the most significant release in the project's history. Here's everything you need to adopt it confidently.
What's New in Tailwind CSS v4
The Oxide Engine: Near-Instant Builds
Tailwind v4 ships with Oxide, a Rust-based engine that replaces the previous JavaScript/PostCSS pipeline. The performance improvement is substantial:
| Tailwind v3 | Tailwind v4 | |
|---|---|---|
| Full build | ~3.5s | ~0.3s |
| Incremental rebuild | ~200ms | ~4ms |
| HMR update | ~100ms | ~1ms |
For large projects with many utility classes, the improvement is even more dramatic. HMR updates that previously took a noticeable second now happen before you've finished looking at the screen.
CSS-Native Configuration
The tailwind.config.js file is gone for most use cases. Configuration now lives directly in your CSS file using @theme:
/* app/globals.css */
@import "tailwindcss";
@theme {
/* Typography */
--font-sans: "Inter", ui-sans-serif, system-ui;
--font-mono: "JetBrains Mono", ui-monospace;
/* Brand colours */
--color-primary: #4f46e5;
--color-primary-foreground: #ffffff;
--color-brand-50: oklch(97% 0.02 265);
--color-brand-500: oklch(55% 0.18 265);
--color-brand-900: oklch(25% 0.12 265);
/* Custom spacing */
--spacing-18: 4.5rem;
--spacing-22: 5.5rem;
/* Breakpoints */
--breakpoint-3xl: 120rem;
/* Border radius */
--radius-xl: 1rem;
--radius-2xl: 1.5rem;
}
These tokens are just CSS custom properties, you can use them anywhere in your CSS, not just in Tailwind utilities. They're also accessible from JavaScript via getComputedStyle.
Dynamic Utility Generation
Tailwind v4 scans your templates and generates utilities on demand. You no longer need to configure a content array, the engine automatically finds your template files. Arbitrary values like pt-[17px] or grid-cols-[repeat(3,_200px)] work without a safelist.
Container Queries Built In
Container queries are now a first-class feature without any plugin:
<!-- The @container on the parent enables container query children -->
<div class="@container">
<div class="grid grid-cols-1 @sm:grid-cols-2 @lg:grid-cols-3 gap-4">
<!-- Cards respond to their container's width, not the viewport -->
<div class="card">...</div>
</div>
</div>
Container queries are the correct solution for component-level responsiveness, a sidebar card and a main content card with the same component shouldn't need separate media queries. They respond to their own context.
3D Transform Utilities
Native CSS 3D transforms are now in Tailwind's core:
<div class="group perspective-1000">
<div class="transition-transform duration-500 group-hover:rotate-y-12 group-hover:rotate-x-3">
Hover me for a 3D tilt
</div>
</div>
No custom plugins or @apply workarounds needed.
Color with OKLCH
Tailwind v4's default colour palette uses OKLCH colour space, which provides more perceptually uniform colour scales. Custom colours defined with OKLCH integrate seamlessly with the built-in palette.
Migrating from Tailwind v3
The Official Codemod
Run the upgrade tool first, it handles the majority of the migration automatically:
npx @tailwindcss/upgrade
The codemod:
- Converts
tailwind.config.js/.tsto@themeCSS blocks - Updates deprecated class names (
shadow→shadow-sm,blur→blur-sm) - Updates
@applyusage where necessary - Removes the PostCSS config if it's only used for Tailwind
After running it, review the diff carefully. The codemod is thorough but can't handle all edge cases, particularly complex theme() function usage in custom CSS.
Manual Migration Steps
Step 1: Update your imports
/* v3 */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* v4 */
@import "tailwindcss";
Step 2: Move your config to CSS
// v3: tailwind.config.ts
export default {
theme: {
extend: {
colors: {
brand: {
50: "#eef2ff",
500: "#6366f1",
900: "#312e81",
},
},
fontFamily: {
sans: ["Inter", "sans-serif"],
},
},
},
};
/* v4: globals.css */
@theme {
--color-brand-50: #eef2ff;
--color-brand-500: #6366f1;
--color-brand-900: #312e81;
--font-sans: "Inter", sans-serif;
}
Step 3: Update deprecated utilities
Several v3 utilities were renamed for clarity:
| v3 | v4 |
|---|---|
shadow |
shadow-sm |
shadow-sm |
shadow-xs |
blur |
blur-sm |
rounded |
rounded-sm |
ring |
ring-3 |
Step 4: Update PostCSS config
If you were using PostCSS solely for Tailwind, you can remove it entirely. For projects that need PostCSS for other plugins (autoprefixer, postcss-import), the Tailwind v4 PostCSS plugin still exists but is separate from the Oxide engine.
Setting Up Tailwind v4 in a New Next.js Project
# Create a new Next.js project
npx create-next-app@latest my-app
# Install Tailwind v4
npm install tailwindcss @tailwindcss/vite
# Or with PostCSS:
npm install tailwindcss @tailwindcss/postcss
With Next.js's Turbopack (the default in Next.js 15+), use the Vite plugin for optimal performance. In next.config.ts:
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
// Turbopack is enabled by default in Next.js 15
};
export default nextConfig;
In your global CSS:
/* app/globals.css */
@import "tailwindcss";
@theme {
--font-sans: "Inter Variable", ui-sans-serif;
--color-background: #ffffff;
--color-foreground: #0a0a0a;
}
That's it. No tailwind.config.ts, no content array, no PostCSS config.
Practical Patterns in v4
Dark Mode
Dark mode works the same way, add the dark: variant. You can configure the strategy in CSS:
@import "tailwindcss";
/* Class-based dark mode (default in v4) */
@variant dark (&:where(.dark, .dark *));
/* Or media query based: */
@variant dark (@media (prefers-color-scheme: dark));
Custom Variants
Creating custom variants is now done entirely in CSS:
@variant hocus (&:hover, &:focus);
@variant supports-grid (@supports (display: grid));
<button class="hocus:ring-2 hocus:ring-indigo-500">
Hover or focus for ring
</button>
Component Patterns with @layer
@layer components {
.btn {
@apply inline-flex items-center justify-center gap-2 rounded-lg px-4 py-2 font-semibold transition-colors;
}
.btn-primary {
@apply btn bg-indigo-600 text-white hover:bg-indigo-700 focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2;
}
.btn-outline {
@apply btn border border-gray-200 bg-white text-gray-700 hover:bg-gray-50;
}
}
Should You Upgrade Now?
New projects: Start with v4. The setup is simpler, the performance is dramatically better, and you won't carry any v3 migration debt.
Existing projects: The codemod handles most of the migration, but budget time for a careful review. Projects with complex tailwind.config.ts files, many custom plugins, or heavy use of theme() functions in CSS will need more attention. Set aside a day for a medium-sized project, a few days for a large one.
The performance gains alone, 10x faster builds, 1ms HMR, are worth the migration effort for any active codebase. If you need help with frontend design and implementation in your project, Codolve works with Tailwind v4 in production.
Frequently Asked Questions
Does Tailwind v4 still require PostCSS?
No. The new Oxide engine works without PostCSS. A PostCSS plugin still exists for projects that need PostCSS for other reasons (autoprefixer, custom transformations), but it's no longer required for Tailwind itself.
Can I use Tailwind v4 with Vite, Webpack, or other bundlers?
Yes. Tailwind v4 ships first-class plugins for Vite, Next.js (via Turbopack), and a PostCSS plugin for Webpack and other bundlers. Support for Rspack and Bun is also available.
Does v4 still have a JIT mode?
JIT (Just-in-Time) compilation was the big innovation of Tailwind v3. In v4, JIT is the only mode, the Oxide engine is JIT by default, and it's dramatically faster than v3's JIT implementation.
What happens to my custom plugins?
Simple plugins that add utilities can often be replaced by @theme and @layer components in CSS. Complex plugins that use JavaScript APIs will need to be migrated or replaced. The v4 documentation has a migration guide specifically for plugin authors.
Is the tailwind.config.ts file completely removed?
For most projects, yes, everything moves to CSS. However, a minimal tailwind.config.ts is still supported if you need to configure content paths for edge cases, or integrate with tooling that reads the config file. Most users won't need it.
Tags





