Jordan Park
Back
·Jordan Park

Tailwind CSS v4: A Practical Guide to the New Architecture

Tailwind v4 ditches the config file in favor of CSS-native configuration. Here's what the migration looks like in practice and what the new architecture gets right.

Tailwind CSSCSSFrontendBuild Tools

Tailwind CSS v4 is a near-complete rewrite. The familiar utility classes are still there, but the underlying engine — and how you configure it — has changed fundamentally. Here's what you need to know.

CSS-first configuration

The biggest shift: no more tailwind.config.js. Everything now lives in your CSS file using CSS custom properties and @theme:

@import "tailwindcss";

@theme {
  --color-brand: oklch(0.62 0.19 252);
  --font-display: 'Playfair Display', serif;
  --radius-lg: 0.75rem;
}

These variables are automatically available as utilities (bg-brand, font-display, rounded-lg). It's surprisingly clean — your design tokens live next to your reset and base styles, all in one file.

The new engine

v4 uses a Rust-based parser (Oxide) and no longer generates a full CSS file at build time. Instead, it scans your source files and generates only what's needed, on demand. The practical result: faster builds and no more purge configuration.

Cold build times on a mid-size project went from ~800ms to ~120ms on my machine.

oklch colors

The default palette is now in oklch — a perceptual color space that gives you more accurate lightness steps across hues. The semantic meaning of color scales (like blue-500) is more consistent than the old hex-based palette.

--color-blue-500: oklch(0.6 0.19 252);

Migration pain points

The config migration is mostly mechanical but has a few gotchas:

  • theme.extend patterns need to move to @theme blocks
  • Some plugins haven't been updated to the v4 API yet
  • @apply inside @layer behaves differently in a few edge cases

The official upgrade guide covers these well. Budget a half-day for a medium-sized project.

Worth it?

Yes, especially for greenfield projects. The CSS-native configuration is genuinely better — it's more portable, easier to inspect, and removes a JavaScript dependency from your styling pipeline. The performance improvements are real too.