Articles

Tailwind CSS v4: The CSS-First Rewrite, Explained

Tailwind v4 rewrites the engine from scratch for dramatically faster builds and moves configuration into CSS itself. Here's what changed and how to work with it.

Takina Takina · · 4 min read
A stylized browser window and layout

Tailwind CSS v4 is not a feature release — it’s a ground-up rewrite. The engine is new, the configuration model is new, and several things you learned for v3 work differently. That’s worth understanding before you upgrade a production project.

A new engine, built for speed

The original Tailwind engine leaned heavily on PostCSS and a JavaScript-based class scanning step. v4 replaces that with a new high-performance Rust-powered core. On large projects, incremental rebuilds that once took hundreds of milliseconds now feel instant — qualitatively, it’s an order-of-magnitude improvement on big codebases. Cold builds are dramatically faster too.

The practical consequence is that the “Tailwind is slow” complaint mostly disappears. If you’ve been reaching for lighter alternatives purely for build performance, that trade-off has changed.

Configuration moves into CSS

The single biggest conceptual shift in v4 is where configuration lives. In v3, you maintained a tailwind.config.js file where you extended the theme, set content paths, and registered plugins. In v4, configuration moves into CSS via the @theme at-rule.

You import Tailwind and define your design tokens in a single stylesheet:

/* v3 approach — tailwind.config.js */
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./src/**/*.{html,js}"],
  theme: {
    extend: {
      colors: {
        brand: "#e63946",
      },
    },
  },
};
/* v4 approach — your main CSS file */
@import "tailwindcss";

@theme {
  --color-brand: #e63946;
  --font-sans: "Inter", sans-serif;
  --spacing-18: 4.5rem;
}

The @import "tailwindcss" line replaces the old three-line base/components/utilities import. The @theme block is where you define or override design tokens — fonts, colors, spacing, radii, and so on.

Design tokens as CSS custom properties

Every token you define in @theme is automatically exposed as a CSS custom variable, and the corresponding utility classes are generated from it. If you write --color-brand: #e63946, Tailwind generates bg-brand, text-brand, border-brand, and so on, and the variable --color-brand is available anywhere in your CSS.

This matters for a few reasons. Your design system is now a set of CSS variables — readable by any JavaScript, usable in custom CSS rules, and inspectable in DevTools without any special tooling. The tight coupling between the JS config file and the generated classes is gone.

Automatic content detection

In v3, the content array in your config file was one of the most common sources of bugs — miss a glob and your classes get purged in production. In v4, content detection is automatic. The engine scans your project files using heuristics that cover most project structures without any configuration. You can still add explicit sources if you need them, but you don’t have to.

Container queries built in

One of the headline additions is first-class container query support — no plugin required. In v3, you needed the official @tailwindcss/container-queries plugin. In v4, container query variants are part of the core framework.

You mark an element as a container and query it:

<div class="@container">
  <div class="flex-col @md:flex-row flex gap-4">...</div>
</div>

The @md: prefix applies styles when the nearest ancestor container is at least as wide as the md breakpoint. This pairs naturally with component-driven design — a card or sidebar can respond to the space it’s given rather than the viewport width. For a deeper look at the underlying CSS feature this wraps, see CSS Container Queries: Components That Adapt to Their Container.

Modern CSS under the hood

v4 leans on features that simply didn’t have broad browser support a few years ago. Cascade layers (@layer) organize styles without specificity fights. color-mix() powers things like opacity modifiers. The generated CSS is leaner and more idiomatic — it looks like CSS you’d write by hand, rather than a mass of overrides.

This is also why v4 can drop some of the workarounds v3 needed. The minimum browser target is modern evergreen browsers; if your project needs to support older environments, check the compatibility notes before upgrading.

Migrating from v3

The Tailwind team ships an official upgrade tool that handles the mechanical parts: renaming changed utilities, converting your tailwind.config.js to @theme directives, and updating the import syntax. For most projects, running it gets you most of the way there.

A few things to review manually:

  • Arbitrary values and custom plugins may need rework depending on how they were structured.
  • JIT-mode configs are now the only mode (JIT has been the default since v3 anyway, so this is rarely a surprise).
  • CSS specificity can shift when cascade layers are involved — spot-check your most complex style overrides.

For projects also running Astro, the framework’s Tailwind integration is updated for v4. And if you’re tuning production performance, the faster builds complement the runtime work covered in the Core Web Vitals guide.

The takeaway

Tailwind v4 is a meaningful upgrade, not just a version bump. The new engine makes build performance a non-issue, the CSS-first configuration model reduces context switching, and having design tokens as native CSS variables is genuinely useful. The migration is not zero-effort — there are real API changes — but the official upgrade tool handles the bulk of it, and the new model is cleaner once you’re on it.

If you’re starting a new project, v4 is the obvious choice. If you’re upgrading an existing one, run the upgrade tool in a branch, audit the output, and test your custom utilities carefully.

Takina Takina · · 4 min read

CSS object-fit and object-position, Explained

object-fit controls how an image or video is cropped inside its box, and object-position controls which part of it stays visible. How they work together.

#CSS #Web Development #Frontend
Takina Takina · · 5 min read

CSS inherit, initial, unset & revert Explained

CSS's four global keywords control where a property's value comes from. How inherit, initial, unset, and revert differ, with a comparison table.

#CSS #Web Development #Frontend