Back to Blog
Web Development 8 min read

Tailwind CSS v4: What Changed and How to Migrate

M
Mathew· January 10, 2025

Everything you need to know about Tailwind CSS v4 — CSS-first configuration, the new @theme directive, performance improvements, and a step-by-step migration guide.

We upgraded several projects to Tailwind CSS v4 over the past few months, and it took a while to fully wrap our heads around the scope of the changes. It's not just a version bump — it's a meaningfully different mental model. Here's what changed and how to migrate without breaking your existing setup.

The Biggest Change: CSS-First Configuration

Tailwind v4 eliminates tailwind.config.js. Your configuration now lives directly in CSS:

/* In your main CSS file */
@import "tailwindcss";

@theme {
  --color-brand: #009688;
  --color-brand-dark: #007A6B;
  --color-accent: #FF6B35;
  --font-sans: "Inter", sans-serif;
  --radius-card: 1rem;
}

That's it. No JavaScript config file, no content array to maintain, no theme.extend object. The @theme directive registers CSS custom properties as design tokens, and Tailwind automatically generates utility classes from them.

So if you define --color-brand: #009688, you automatically get bg-brand, text-brand, border-brand, ring-brand, and all their opacity variants. It clicks once you see it in action, and it's genuinely elegant.

Performance: Actually Impressive

The internal engine was rewritten using Lightning CSS (a Rust-based CSS parser and transformer). Build times improved dramatically. On a real project with roughly 200 components, we went from a 2.3-second Tailwind build to 0.4 seconds — about a 5x speedup.

The new engine also handles modern CSS features natively, which means less PostCSS plugin dependency and more reliable output across browser targets.

The @import Change

Previously, you had three @tailwind directives at the top of your CSS:

/* v3 — old way */
@tailwind base;
@tailwind components;
@tailwind utilities;

In v4, it's a single import:

/* v4 — new way */
@import "tailwindcss";

If you're on a bundler that doesn't handle CSS @import (some older webpack configs), you'll need to update your tooling. Vite handles it out of the box. Next.js with the PostCSS plugin also works, but you may need to add @tailwindcss/postcss explicitly.

Content Detection Is Now Automatic

In v3, you had to specify which files Tailwind should scan:

// v3 tailwind.config.js
content: ["./src/**/*.{js,ts,jsx,tsx}"]

In v4, this is automatic. Tailwind scans your project files without configuration. This eliminates a common source of confusion ("why isn't my class being generated?") that happened when someone forgot to add a new directory to the content array.

Arbitrary Values Still Work

Good news: arbitrary values like bg-[#FF6B35], w-[calc(100%-2rem)], and text-[clamp(1rem,5vw,3rem)] work exactly the same. If you've been relying on arbitrary values heavily, nothing breaks here.

What Broke for Us

The config migration was the main friction point. Any custom colors, fonts, or spacing defined in tailwind.config.js need to move to @theme blocks in CSS. For small projects, this is a 15-minute job. For larger design systems with deeply customized configurations, plan for a few hours.

Some third-party component libraries that ship their own Tailwind config had compatibility issues during the initial v4 release window. Most have since published v4-compatible versions. Check your dependencies before upgrading.

Step-by-Step Migration

  1. Update packages: npm install tailwindcss@latest @tailwindcss/postcss@latest
  2. Replace the three @tailwind directives with @import "tailwindcss"
  3. Move all theme values from tailwind.config.js into an @theme {} block in your CSS file
  4. Delete tailwind.config.js (or keep it empty if a plugin requires it)
  5. Remove the content array configuration — no longer needed
  6. Update your PostCSS config to use @tailwindcss/postcss instead of tailwindcss
  7. Run a build and check the output — class generation issues will surface immediately

Should You Upgrade Now?

For new projects: yes, start with v4 from day one. The CSS-first config is cleaner to maintain, and you get the performance improvements for free.

For existing v3 projects: there's no urgent reason to upgrade unless you're hitting build performance issues or want to clean up a bloated config. Tailwind v3 still receives security fixes. If you do upgrade, budget a half-day for a typical mid-sized project, and run your visual regression tests (if you have them) after the migration to catch any rendering differences.

Tailwind CSSCSSFrontendWeb Development
Let's Work Together

Ready to Work With a Software Development Agency That Delivers?

Get a free consultation and project estimate within 24 hours. No fluff — just an honest conversation about your goals, timeline, and budget.

Free consultation24-hour responseNo commitment required