EmpireUI
Get Pro
← Blog8 min read#tailwind v4#css#new features

Tailwind CSS v4: Every New Feature Worth Knowing About

Tailwind CSS v4 ships a rewritten engine, native CSS variables, and a new config format. Here's everything that actually matters for your day-to-day workflow.

Developer writing Tailwind CSS code on a laptop screen at desk

What Actually Changed in Tailwind CSS v4

Tailwind v4 isn't a minor bump. The entire engine got rewritten in Rust — yes, the whole scanner and generator — and the performance difference is real. Full builds that used to take 1.2 seconds are now done in under 100ms on most projects.

Honestly, the biggest shift isn't speed. It's the move away from a JavaScript config file toward a CSS-first configuration model. Your tailwind.config.js is optional now. You define your theme directly in CSS using @theme, and the cascade does the rest.

Worth noting: this isn't just a DX upgrade. The new architecture means Tailwind emits real CSS custom properties for every design token. That changes how you integrate with other tools, including component libraries. If you're building with something like Empire UI, you'll want to know how your token layer interacts with Tailwind's new output format.

The v4.0 release dropped in early 2025, and by mid-2026 most major frameworks have updated their starter templates to use it by default. If you're still on v3, the migration path exists but it's not automatic — expect to spend an afternoon on a medium-sized project.

The New CSS-First Configuration with @theme

This is the change you'll feel every single day. Instead of exporting a giant object from tailwind.config.js, you write your design tokens directly in CSS:

@import "tailwindcss";

@theme {
  --color-brand: #6d28d9;
  --color-brand-light: #8b5cf6;
  --font-sans: 'Inter', sans-serif;
  --spacing-18: 4.5rem;
  --radius-card: 12px;
}

That's it. Tailwind picks up every -- variable inside @theme and generates corresponding utility classes. So --spacing-18 becomes p-18, m-18, gap-18, and so on. The mental model is much closer to how CSS actually works.

In practice, this collocates your design tokens with your styles instead of scattering them across a separate config file. It also means your editor's CSS IntelliSense starts being useful for your own tokens, not just Tailwind's defaults. That said, if you have a complex multi-package monorepo with shared config, you'll still want to think carefully about where that @theme block lives.

One more thing — @theme supports @media and @layer inside it. Dark mode tokens, for example, can live in a prefers-color-scheme block right there in your theme definition.

Container Queries Are Now Built In

No plugin. No @tailwindcss/container-queries. Container queries land as first-class utilities in v4.

You get @container, @sm, @md, @lg variants out of the box. The syntax looks like responsive variants you already know — prefix a utility with the container size and you're done. If you've been using the official plugin on v3, migration is mostly a find-and-replace, but pay attention to named containers since the syntax shifted slightly.

<div className="@container">
  <div className="grid grid-cols-1 @md:grid-cols-2 @lg:grid-cols-3 gap-6">
    {items.map(item => (
      <Card key={item.id} {...item} />
    ))}
  </div>
</div>

Container queries make component-driven design genuinely viable without media query spaghetti. Your Card component doesn't need to know if it's in a sidebar or a full-width layout — it just responds to its container. This is especially handy when you're composing UI from a library and you don't control the parent context.

3D Transforms, Gradients, and New Utilities

Tailwind v4 adds rotate-x-*, rotate-y-*, perspective-*, and transform-style-preserve-3d as native utilities. Before v4, doing a card flip or a 3D button press required dropping into arbitrary [transform:rotateY(180deg)] values or custom CSS. Now it's just rotate-y-180.

Gradients got a proper upgrade too. You can now specify gradient positions, use conic-gradient via bg-conic-*, and control gradient interpolation color space — which means you can get those perceptually smooth transitions that used to require hand-rolled CSS. The gradient generator at tools/gradient-generator shows you what's possible when these new properties are combined.

The not-* variant is new and surprisingly useful. not-hover:opacity-50 means "apply this unless the element is hovered" — which reads cleaner than the old workaround of managing default + hover states separately. Quick aside: group-not-hover and peer-not-checked also work, so the whole modifier system got more expressive.

Shadow utilities now include inset-shadow-* natively, no more [box-shadow:inset_...] hacks. If you're building neumorphic or inset-pressed UI — check the box shadow generator for inspiration — this alone saves meaningful time.

The Vite Plugin and Zero-Config Setup

The old PostCSS-only setup still works, but the recommended path in 2026 is the official Vite plugin. Install @tailwindcss/vite, add it to your vite.config.ts, and you're done. No postcss.config.js, no autoprefixer (Tailwind handles prefixing now), no content array to maintain.

// vite.config.ts
import tailwindcss from '@tailwindcss/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [tailwindcss()],
});

The plugin scans your source files automatically using a new heuristic scanner that doesn't require you to list paths. It's fast enough that you don't need to worry about scanning too much — the Rust-based scanner handles even large repos in milliseconds. That said, if you have unusual file extensions or generated files, you can still configure content explicitly in your CSS with @source.

Look, the zero-config experience is genuinely better. It removes one of the main friction points people hit when setting up Tailwind fresh. The fewer decisions you have to make before you can write a flex gap-4, the better.

Breaking Changes You Need to Handle

Some v3 utilities got renamed or removed. shadow-sm is now shadow-xs, the old shadow maps to shadow-sm, and ring defaults changed. These aren't huge deals but they will break visual regression tests if you upgrade without reading the changelog.

The JIT mode distinction is gone because v4 is JIT-only, always. If you were relying on any v2-era class generation behavior that JIT didn't support, now's the time to audit. Also, the theme() function in CSS still works but you're encouraged to use CSS variables directly — var(--color-brand) instead of theme('colors.brand').

Arbitrary values got stricter. Some edge-case syntaxes that accidentally worked in v3 now require explicit quoting or different syntax. The official upgrade guide has a full list, and the npx @tailwindcss/upgrade codemod handles most of it automatically — but run it on a branch and review the diff before merging.

Worth noting: if your project uses third-party component libraries or design systems, check their Tailwind v4 compatibility before upgrading. Many libraries still pin to v3 as of early 2026. Mixing v3 and v4 Tailwind instances in one project is unsupported and will cause you pain.

Should You Upgrade Right Now?

If you're starting a new project in 2026, use v4. There's no reason not to. The defaults are better, the DX is better, and you won't be carrying v3 baggage from day one.

For existing projects, it depends on size and test coverage. Small apps: do it over a weekend. Medium apps: plan a proper migration sprint and use the codemod. Large apps with extensive visual testing: wait until your component library ecosystem catches up, or budget real time for the visual diffs.

The CSS-first theme model pairs well with design-system-forward workflows. If you're building custom components and pulling in patterns from Empire UI or similar libraries, the ability to define your token layer in CSS and have Tailwind generate utilities from it is genuinely useful — it keeps your design language in one place instead of split between CSS and JS.

In practice, v4 is the version where Tailwind stops feeling like a generator bolted onto CSS and starts feeling like a CSS-native tool. That's worth something, especially as native CSS features keep catching up.

FAQ

Do I need to rewrite my tailwind.config.js to upgrade to v4?

Not immediately — the JS config still works in v4 via a compatibility layer. But the long-term direction is CSS-first config with @theme, and you'll miss out on some v4 features if you stay on the old format.

Is Tailwind v4 compatible with Next.js and Vite?

Yes. The official Vite plugin is the recommended setup, and Next.js 15+ supports v4 via PostCSS. Just follow the framework-specific install guide in the v4 docs.

What happened to the tailwind.config.js content array?

It's gone by default. The new Rust scanner auto-detects source files in your project. You can still use @source in your CSS if you need to opt in specific paths or generated files.

Can I use Tailwind v4 with CSS Modules or vanilla CSS files?

Yes — you import Tailwind via @import "tailwindcss" in your main CSS file, and it works alongside CSS Modules without conflict. Your custom properties from @theme are globally available too.

Free components in 40 styles
React & Tailwind, copy-paste ready.
Browse →

Read next

Tailwind CSS v4 Migration Guide: From v3 Config to CSS-FirstTailwind CSS Animations: Every Built-In + How to Add CustomGlassmorphism in 2026: Is the Trend Still Worth Using?React 19: What Actually Changed and What You Should Use Now