· tailwind / tailwind-v4 / css

Tailwind v4: What Changed and Is It Worth Upgrading?

Tailwind v4 stable since v4.1. New projects: upgrade now. Existing v3: run migration tool on a branch. Hard browser floor: Safari 16.4+, Chrome 111+.

By Ethan

1,649 words · 9 min read

Upgrade new projects to Tailwind v4 today. For existing v3 projects: run the automated migration tool on a dedicated branch — the migration is mostly mechanical, but there are real breaking changes that need your attention. v4 is production-stable as of v4.1 (April 2025). Hard blocker: if you support Safari < 16.4, Chrome < 111, or Firefox < 128, stay on v3.4 until your analytics clear those browsers.

Who this is for

Developers with an existing Tailwind v3 project deciding whether to move to v4. If you are starting fresh, v4 is the obvious choice and this review does not address that case. Everything below assumes you have a running v3 codebase and want to know what the upgrade actually costs.

What we tested

Tailwind v4.2 versus v3.4.17, using benchmarks from the official v4 announcement run on the Catalyst project by Tailwind Labs (Apple M-series hardware). Ecosystem checks were done May 2026 against live documentation and open GitHub issues. We did not run our own benchmark suite — the numbers below come from Tailwind Labs’ published measurements.

CSS-first config

The biggest conceptual shift in v4 is where you configure Tailwind. The tailwind.config.js file moves into CSS.

v3:

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: { brand: '#5c6ac4' },
    },
  },
}

v4:

@import "tailwindcss";

@theme {
  --color-brand: #5c6ac4;
}

The @tailwind base, @tailwind components, @tailwind utilities directives are gone. One @import "tailwindcss" replaces all three.

If you need to keep a JS config file — for monorepo sharing or plugin compatibility — it still works alongside the CSS import:

@import "tailwindcss";
@config "../../tailwind.config.js";

corePlugins and separator are gone with no equivalent. safelist moves to CSS: use @source inline() instead (see upgrade guide). If your project relies on corePlugins or separator, plan time to assess the impact before upgrading. The resolveConfig() utility is also removed — if anything in your build pipeline calls it, that needs a fix.

If you’re still weighing whether utility-first CSS is the right long-term strategy, Tailwind CSS vs CSS Modules covers what actually compounds over 1–3 years.

Performance

v4 introduces the Oxide engine, rewritten in Rust. The benchmarks on Catalyst:

Scenariov3v4Improvement
Full build378 ms100 ms3.78× faster
Incremental (new CSS classes)44 ms5 ms8.8× faster
Incremental (no new CSS)35 ms0.19 ms182× faster

The third row is the one you feel in daily work. When you edit a JSX file and don’t add any new Tailwind class names, v4 skips CSS regeneration entirely. Sub-millisecond feedback is effectively instant. For full builds, 3.78× faster matters most on CI and cold starts.

One nuance worth noting: Tailwind’s blog describes the engine as “rewritten in Rust,” but the exact Rust vs. other-language split inside Oxide is not publicly documented. The benchmark numbers are what you should base expectations on.

Tailwind v4 breaking changes

The upgrade guide covers all of these. Here are the ones most likely to cause visible regressions in a real project.

Utility class renames

The shadow, blur, and rounded scales shifted one step down:

v3 classv4 equivalent
shadowshadow-sm
shadow-smshadow-xs
roundedrounded-sm
rounded-smrounded-xs
blurblur-sm
blur-smblur-xs

This is exactly the kind of change that looks correct when you spot-check individual components but wrong when you see them side by side. Do not hand-fix these — run the automated migration tool and review the diff.

Ring default changed

v3: ring adds a 3px blue-500 ring. v4: ring adds a 1px currentColor ring.

If you use ring for keyboard focus indicators, your focus styles changed — both thickness and color. Check your focused interactive elements.

Border color changed

v3: border defaults to gray-200. v4: border defaults to currentColor.

Borders that were subtle may become solid and visually heavy. Search for bare border classes without an explicit color and review them.

Opacity utilities removed

bg-opacity-50, text-opacity-75, border-opacity-25 and the rest are gone. Use the slash syntax instead:

<!-- v3 -->
<div class="bg-black bg-opacity-50 text-white text-opacity-90">

<!-- v4 -->
<div class="bg-black/50 text-white/90">

The automated tool rewrites these, but if you have dynamically constructed class strings in JavaScript, those need manual attention.

Important modifier flipped

!flex (bang-prefix) → flex! (bang-suffix). The v3 prefix syntax is deprecated but still works for compatibility — migrate when convenient.

Sass and Less dropped

v4 dropped PostCSS support for Sass and Less. If your project runs Tailwind through a Sass or Less processor, that path is gone. Pure CSS only.

Browser floor

v4 depends on CSS features — cascade layers (@layer), color-mix(), logical properties — that landed in:

  • Safari 16.4+
  • Chrome 111+
  • Firefox 128+

This is not a caniuse soft recommendation; it is a hard requirement. v4.1 added fallbacks for some cases, but the floor is real. Check your analytics before committing to an upgrade.

Ecosystem

shadcn/ui

Tailwind v4 preview support landed in February 2025 — the shadcn/ui team described it explicitly as “the first preview of Tailwind v4 and React 19 support,” not general availability. All components were updated for the preview, the CLI defaults to v4 for new installs, and colors migrated from HSL to OKLCH. If you are on a v3 project using shadcn/ui, the existing components remain backward-compatible — you do not need to upgrade shadcn just because you want to upgrade Tailwind. For new projects, v4 is the default.

tailwindcss-animate is deprecated in v4. Tailwind now ships built-in CSS animations that cover the same use cases.

Next.js

create-next-app --tailwind still installs Tailwind v3.4.x as of mid-2026. Tailwind v4 is not yet the Next.js scaffold default. If you scaffold a new Next.js project and want v4, run the upgrade tool after scaffolding.

Turbopack had compatibility issues with v4 in the early releases — these were addressed in v4.1. Webpack (Next.js’s default bundler) works fine with v4. If you are on Turbopack and v4.0, upgrading to v4.1+ should clear the instability. For HMR and build-speed numbers outside the Next.js context, see Turbopack vs Vite.

Vite projects work smoothly with v4 from v4.0. If you are evaluating Tailwind v4 for a new project, Vite is the path of least resistance — our Vite vs Webpack guide covers when migrating your build setup pays off.

Headless UI and Radix

No v4-specific blockers. Both libraries are unstyled — they do not depend on Tailwind internals or class naming conventions. They work with whatever Tailwind version you run.

Stability timeline

v4.0 shipped with production issues that hit real teams:

  • Dev/prod CSS mismatches in Astro + Vite setups
  • @apply breakage in certain configurations
  • Dark mode edge cases
  • Turbopack compatibility failures

Teams that adopted v4.0 in the first weeks ran into these. Some downgraded to v3.4. The GitHub issue tracker for v4.0 reflects this — the discussion threads are worth reading if you want the specifics.

v4.1 (April 3, 2025) addressed the core complaints: browser compatibility fallbacks for cascade layers, @apply reliability fixes, dark mode behavior fixes, Turbopack improvements. v4.2 continued incrementally from there.

If you tried v4 during the v4.0 window and hit issues, the current release is a different experience. The v4.0 → v4.1 gap was the stabilization window.

Upgrade decision matrix

SituationRecommendation
New project, modern browser targetsStart on v4. No reason to start on v3.
Existing v3 project, modern browsers onlyUpgrade. Dedicate a branch, run the migration tool, review shadow/ring/border changes. Budget half a day for a small project, more for a large one.
Safari < 16.4 / Chrome < 111 / Firefox < 128 trafficStay on v3.4 until your browser analytics clear the floor.
Project uses corePlugins or separatorAssess impact before upgrading. These have no v4 equivalent. safelist moves to @source inline() — lower risk.
Project preprocesses through Sass or LessInvestigate alternative build path first.
Tried v4.0 and it broke thingsRetry on v4.1+. The early issues are fixed.

Caveats

Automated migration tool: The official npx @tailwindcss/upgrade handles most mechanical changes — class renames, syntax updates, config migration. Run it on a dedicated branch and treat the output as a diff to review, not a ready-to-ship artifact. Pay particular attention to any dynamically constructed class strings in JavaScript files, which the tool may not catch.

Rust claim nuance: The “rewritten in Rust” framing is Tailwind Labs’ own description. The internal architecture of Oxide — which parts are Rust, which are not — is not publicly documented in detail. The benchmark numbers are real and independently reproducible; the implementation details are not something we verified.

No affiliate links: Tailwind Plus exists — 500+ v4-native UI component blocks, the Catalyst React component kit, one-time purchase. There is no confirmed public affiliate program for Tailwind Plus. No links in this article go through an affiliate tracker.

References