Skip to content
Journal

Engineering

Tailwind v4: Notes from Our First Week in Production

Headshot of Alex Fujimoto
Alex Fujimoto
January 28, 2025 · 3 min read

Tailwind CSS v4.0 landed last Wednesday, and because we had been tracking the beta since November, we had it in production on a client marketing site within five days. Not because we chase shiny releases, but because this one solves problems we actually had. Here are field notes, not a changelog recap.

The config file is dead and I am not mourning it

The headline change: configuration moves from tailwind.config.js into CSS itself. Your design tokens live in a @theme block, as native CSS custom properties.

@import "tailwindcss";

@theme {
  --font-display: "Söhne", sans-serif;
  --color-ink: oklch(0.21 0.02 260);
  --color-signal: oklch(0.68 0.19 35);
  --spacing-gutter: 1.5rem;
}

This sounds cosmetic. It is not. For a studio that hands off codebases to client teams, the JS config was a recurring source of drift: tokens defined in JavaScript, consumed in CSS, documented in Figma, three sources of truth pretending to be one. Now the tokens are CSS variables, which means the browser sees them, our documentation can read them at runtime, and a client's in-house developer can inspect an element and trace a value to its definition without learning our build setup. That is a genuine handoff improvement.

Speed you can feel, not just benchmark

The new engine is fast. Full rebuilds on our mid-size project dropped from about 2 seconds to well under 200 milliseconds, and incremental builds are effectively instant. The practical effect is subtle but real: hot reload stops being a rhythm-breaker during fine-tuning sessions, the exact moments where we do our most detail-heavy CSS work. Designers pairing with engineers notice it too. Nobody says "fast compiler" out loud, but the sessions flow better.

Automatic content detection also removed a whole category of onboarding bug. No more explaining to a new contributor why their classes are not generating because a glob pattern missed a directory.

Things that bit us

Honesty section, because every migration writeup needs one:

  • The upgrade tool is good, not magic. It handled about 90 percent of our codebase. The remaining 10 percent was deprecated utilities and a few places where we had leaned on JS config functions that have no CSS equivalent. Budget a day, not an hour, for a real project.
  • Browser floor is real. v4 targets modern browsers, Safari 16.4 and up. For most of our clients this is fine. For one client with a large enterprise audience on managed machines, we are staying on v3.4 until their analytics say otherwise. Check your own numbers before migrating anything with revenue attached.
  • Plugin ecosystem lag. A couple of community plugins we relied on were not v4-ready at launch. We rewrote one as plain CSS in an hour, which, frankly, is what v4 wants you to do anyway.

The bigger pattern

Step back and v4 is part of a trend I like: frameworks shedding their proprietary layers and betting on the platform. Cascade layers, color-mix(), container queries, custom properties, all native, all first-class in v4. The framework is becoming a thin, fast convention on top of real CSS rather than a parallel universe.

That matters more now than it would have two years ago, because more of our initial code is machine-generated. The closer our styling layer sits to web standards, the better AI tools handle it and the less exotic knowledge our reviews have to police. Boring platform alignment turns out to be an AI-era feature.

Recommended, with the caveats above. Our default stack for new builds is now v4.

Building something this could apply to?

We take on a small number of flagship projects each quarter.

Start a project