Tailwind CSS v4: What's New? All Features at a Glance
AI generated
</>
tw
Tailwind CSS · v4 · Oxide · CSS-First · Migration
Tailwind CSS v4: What's New?
Oxide Engine, @theme, and CSS-First Explained

Tailwind CSS v4 is not an incremental improvement, it is a complete rearchitecture. The Oxide engine replaces the Node.js-based build process with a Rust-native implementation, @theme replaces tailwind.config.js, and the CSS-first approach fundamentally changes how Tailwind is configured.

14 min read Oxide Engine · @theme · @variant · @utility · @source Tailwind CSS v4.0+

1. Tailwind CSS v4: What Actually Changed?

Tailwind CSS v4 marks the biggest version jump in the history of the framework so far. Unlike the transition from v1 to v2, which mainly brought new utility classes, or v2 to v3, which introduced the JIT compiler, Tailwind CSS v4 is a complete rearchitecture from the ground up. The build stack was migrated from JavaScript to Rust, the configuration format switched from JavaScript to CSS, and the internal processing logic was rewritten entirely. The result is a framework that offers the same familiar utility class API, but with fundamental improvements in performance, flexibility, and closeness to the CSS platform.

The most important conceptual change in Tailwind CSS v4 is the switch to the CSS-first approach. Previously, Tailwind was a tool configured through JavaScript that emitted CSS. In v4, Tailwind is a tool that takes CSS as both input and configuration and emits optimized CSS. This shift has far-reaching consequences: the tooling becomes simpler, the learning curve for CSS developers flattens, and the integration into existing CSS workflows becomes more seamless. For teams already working with CSS custom properties, Tailwind CSS v4 feels like a natural extension rather than a separate framework with its own configuration language.

Important for the assessment: Tailwind CSS v4 is not backward compatible with v3. There are breaking changes to some classes, the configuration method, and the plugin system. For new projects, v4 is clearly the right choice. For existing projects, a migration is required, which can take anywhere from a few hours to several days depending on the complexity of the project.

2. The Oxide Engine: Rust Instead of Node.js

At the core of the changes in Tailwind CSS v4 is the new Oxide engine, a reimplementation of the entire build process written in Rust. In Tailwind v3, the build process was a Node.js application combining PostCSS plugins, JavaScript evaluation of the configuration file, and string matching for class scanning. In v4, Oxide takes over this entire pipeline as native binary code: CSS parsing, class scanning, utility generation, and CSS output, all in Rust.

The performance impact is substantial. In the official benchmarks from the Tailwind CSS v4 developers, full rebuilds were measured up to 3.5x faster, incremental rebuilds up to 8x faster, and initial builds up to 100x faster than Tailwind v3 with the JIT compiler enabled. In practice, this means even large projects with thousands of classes and hundreds of CSS files rebuild within milliseconds. Watch mode reacts to file changes in near real time, a noticeable difference in day-to-day development workflow.


/* main.css: Tailwind CSS v4 entry point (no tailwind.config.js needed) */
@import "tailwindcss";

/* Automatic source detection: Tailwind v4 scans linked files automatically */
/* For explicit paths use @source */
@source "../templates/**/*.{html,php,phtml}";
@source "../src/**/*.{js,ts,vue,jsx,tsx}";

/* @theme replaces the entire "theme" section of tailwind.config.js */
@theme {
  --color-brand-50:  #eff6ff;
  --color-brand-500: #3b82f6;
  --color-brand-900: #1e3a8a;

  --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
  --spacing-18: 4.5rem;
}

/* No postcss.config.js required with the Vite plugin or standalone CLI */
/* Installation: npm install tailwindcss@next @tailwindcss/vite */

The Oxide engine also brings automatic source detection. In Tailwind v3, the content array in tailwind.config.js had to list every file path to be scanned. Tailwind CSS v4 detects most project structures automatically: it follows @import chains, reads linked JavaScript files, and scans standard directories. For projects with non-standard structures, such as Magento themes or PHP templating systems, there is the explicit @source directive as a replacement for the content array.

3. CSS-First Approach: @theme Instead of tailwind.config.js

The CSS-first approach is the most visible change for developers working with Tailwind CSS v4. The @theme directive accepts CSS custom properties with standardized prefixes and generates from them both Tailwind utility classes and native CSS variables on :root. That means configuration and output live in the same language, and design tokens are available at runtime as CSS variables, not just at build time.

The prefix convention in Tailwind CSS v4 @theme is clearly structured: --color-* for all color utilities (bg, text, border, ring, outline, etc.), --font-* for font families, --text-* for font sizes, --leading-* for line heights, --spacing-* for the entire spacing system, --radius-* for border radii, --shadow-* for box shadows, and --blur-* for blur values. A token like --color-brand-600: #2563eb automatically generates bg-brand-600, text-brand-600, border-brand-600, ring-brand-600, and every other color utility.

4. Native @import Support and File Structure

Tailwind CSS v4 processes native CSS @import statements itself, without relying on PostCSS plugins like postcss-import. That means a main file can pull in all partial CSS files via @import, and Tailwind processes the entire tree, including @theme blocks in imported files. The order of imports matters: later declarations override earlier ones, which enables implementing theme overrides for multi-site projects.

Recommended file structure for a Tailwind CSS v4 project: an app.css entry file with @import "tailwindcss", followed by project-specific @import directives for tokens, base layer extensions, and components. Larger projects benefit from a clear split: tokens/colors.css, tokens/typography.css, tokens/spacing.css, components/buttons.css, components/cards.css. This structure is more maintainable than a monolithic CSS file and makes splitting responsibilities across a team easier.


/* Tailwind CSS v4: custom @variant and @utility directives */

/* @variant: defines a new variant modifier (like hover:, focus:, dark:) */
@variant hocus {
  /* Applied when hovered OR focused: combines hover and focus */
  &:hover, &:focus-visible {
    @slot;
  }
}

/* @variant for custom breakpoint modifiers */
@variant tablet {
  @media (min-width: 640px) and (max-width: 1023px) {
    @slot;
  }
}

/* @utility: adds new utility classes to Tailwind's utility layer */
@utility content-auto {
  content-visibility: auto;
}

@utility snap-proximity {
  scroll-snap-type: both proximity;
}

/* Usage in HTML: class="hocus:bg-brand-500 tablet:text-center content-auto" */
/* These are now first-class Tailwind utilities with all variant support */

5. @variant: Defining Custom Variants in CSS

Variants in Tailwind are the prefixes like hover:, focus:, dark:, sm:, that activate utility classes for specific states or contexts. In Tailwind CSS v3, custom variants could only be created through the plugin system in JavaScript. Tailwind CSS v4 makes this possible directly in CSS: the @variant directive defines a new variant name and its associated CSS context. The @slot marker indicates where the generated styles are inserted.

Custom variants in Tailwind CSS v4 with @variant are fully first-class variants. They can be combined with other variants (dark:hocus:bg-brand-500), use responsive prefixes (sm:hocus:text-lg), and work in every context that built-in variants work in. Common use cases: a hocus variant for combined hover and focus states (for better accessibility), a print variant for print styles, or an rtl variant for Arabic and Hebrew text on bilingual sites.

6. @utility: Custom Utility Classes Without JavaScript

The @utility directive in Tailwind CSS v4 makes it possible to define new utility classes directly in CSS that behave like built-in Tailwind utilities. That means variant support, responsive support, and correct CSS layer placement are all handled automatically. In v3, the equivalent result required a plugin written in JavaScript. The @utility directive makes the transition of utilities from plugins to CSS seamless.

An important difference from @layer utilities: classes in @utility are registered by Tailwind CSS v4 as full utilities. They appear in the correct cascade layer, can be combined with any variant, and benefit from future framework features. Classes in @layer utilities, on the other hand, are placed in the same layer but are not registered as framework utilities, a subtle but significant difference on complex projects with many custom utilities.

7. Breaking Changes and Important Behavior Changes

Tailwind CSS v4 has a number of breaking changes that must be accounted for when migrating from v3. The most important ones: the separator for variants remains :, but some deprecated variant combinations no longer work. The class text-opacity-* was replaced by text-[color]/[opacity], for example text-brand-500/80 instead of the old combination of text-brand-500 and text-opacity-80. This new syntax is more elegant and was already available in v3, but in v4 the old pattern has been removed entirely.

The darkMode configuration option from tailwind.config.js is gone entirely in Tailwind CSS v4. Dark mode is now controlled either through the built-in dark: variant (which reacts to prefers-color-scheme by default) or through a custom @variant dark declaration that uses its own selector. That sounds like more effort, but it offers more flexibility: dark mode can be controlled via a CSS variable, a class, or a media query, all without any JavaScript configuration. In addition, the prefix configuration field is gone; in Tailwind CSS v4, a global prefix is set via @import "tailwindcss" prefix(tw).

8. Tailwind CSS v3 vs. v4 Head to Head

A direct comparison of the most important aspects shows exactly what Tailwind CSS v4 improves over v3.

Feature Tailwind CSS v3 Tailwind CSS v4 Change
Build Engine Node.js + PostCSS Rust (Oxide Engine) Up to 10x faster
Configuration tailwind.config.js (JS) @theme in CSS No JavaScript needed
Custom Variants Plugin API in JavaScript @variant in CSS Direct CSS approach
Custom Utilities Plugin addUtilities() @utility in CSS First-class utilities
@import Support Requires postcss-import Natively built in No plugin needed

What does not change in Tailwind CSS v4: the entire utility class API. All familiar classes like flex, grid, p-4, text-lg, bg-blue-500, hover:opacity-80, sm:grid-cols-2 work exactly as before. The HTML does not need to be touched, only the configuration and the build process change. This significantly reduces migration risk: the migration can be limited to the configuration file and the build process, leaving the HTML untouched aside from the few breaking changes to deprecated classes.

9. Migrating from v3 to Tailwind CSS v4

Migrating an existing project to Tailwind CSS v4 begins with installing the new packages. The entry point package is now tailwindcss (for the CLI), or @tailwindcss/vite for Vite projects, and @tailwindcss/postcss for PostCSS setups. The official Tailwind developers provide an automated upgrade tool: npx @tailwindcss/upgrade analyzes the project, converts tailwind.config.js into @theme CSS, and updates the CSS entry file. For most standard projects, this tool handles the bulk of the migration automatically.

What still needs to be checked manually when migrating to Tailwind CSS v4: plugins that use the addUtilities or addComponents API from v3; custom variants created through the plugin system; color opacity classes (text-opacity-*, bg-opacity-*) that have been replaced by the new slash syntax; and the darkMode configuration key. For projects that used PostCSS plugins like postcss-import or autoprefixer: in v4 these are often no longer needed, since Tailwind processes @import natively and modern browsers usually no longer require autoprefixing.


/* Migration example: v3 tailwind.config.js to v4 @theme CSS */

/* === v3: tailwind.config.js ===
module.exports = {
  darkMode: 'class',
  content: ['./src/**/*.{html,js,ts,vue}'],
  theme: {
    extend: {
      colors: {
        brand: { 500: '#3b82f6', 700: '#1d4ed8' },
        accent: '#0ea5e9',
      },
      fontFamily: {
        sans: ['Inter', 'ui-sans-serif', 'system-ui'],
      },
      borderRadius: {
        card: '1rem',
      },
    },
  },
}
*/

/* === v4: app.css (CSS-First) === */
@import "tailwindcss";
@source "../src/**/*.{html,js,ts,vue}";

@theme {
  /* Colors: generates bg-brand-500, text-brand-700, etc. */
  --color-brand-500: #3b82f6;
  --color-brand-700: #1d4ed8;
  --color-accent:    #0ea5e9;

  /* Font family */
  --font-sans: "Inter", ui-sans-serif, system-ui;

  /* Border radius */
  --radius-card: 1rem;
}

/* Dark mode: @variant replaces darkMode: 'class' */
@variant dark (&:where(.dark, .dark *));

10. Summary: Is the Upgrade Worth It?

For new projects, the answer is clear: Tailwind CSS v4 is the right choice. The CSS-first approach is conceptually cleaner, the Oxide engine is substantially faster, and the new @variant and @utility directives make the framework more flexible without the complexity of JavaScript plugins. The learning curve for developers who already know CSS is lower than with v3 and its tailwind.config.js.

For existing projects, the decision depends on complexity. The official upgrade tool handles most standard migrations automatically. Projects with many custom plugins or complex configurations need more manual work. Either way: Tailwind CSS v4 is the framework future development is focused on. In the long run, migration is unavoidable, migrating early is easier than migrating late.

Tailwind CSS v4: The Essentials at a Glance

Oxide Engine

Rust-native build engine, up to 10x faster than v3. No Node.js needed for the core build process anymore.

CSS-First with @theme

tailwind.config.js is replaced by @theme in CSS. Design tokens are available as :root custom properties.

@variant & @utility

Custom variants and utilities directly in CSS without JavaScript plugins. Full variant composability.

Migration

npx @tailwindcss/upgrade for automatic migration. The class API stays identical, only the configuration changes.