TL;DR:
- Tailwind CSS 4 replaces the JavaScript config file with a CSS-first configuration system — your
tailwind.config.jsbecomes@themeblocks in your CSS. - The new Oxide engine (written in Rust and Lightning CSS) is dramatically faster: full builds that took seconds now take milliseconds, and incremental builds are near-instant.
- Most utility class names are unchanged, but some have been renamed or restructured. The official upgrade tool handles the majority of mechanical changes automatically.
Tailwind CSS 4 shipped in stable form in early 2025 and has been the default for new projects since. If you’re migrating an existing v3 project, the changes are significant enough to require a deliberate upgrade path, but the end result is a meaningfully faster development experience and a configuration model that many teams find cleaner.
The Core Change: CSS-First Configuration
In Tailwind v3, you configured everything in tailwind.config.js. In v4, configuration moves into your CSS file using @theme:
Before (v3):
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
brand: {
500: '#6366f1',
600: '#4f46e5',
}
},
fontFamily: {
sans: ['Inter', 'sans-serif'],
}
}
}
}
After (v4):
/* globals.css */
@import "tailwindcss";
@theme {
--color-brand-500: #6366f1;
--color-brand-600: #4f46e5;
--font-sans: 'Inter', sans-serif;
}
The @theme block defines CSS custom properties that Tailwind v4 reads to generate utilities. Any --color-* variable becomes available as bg-{name}, text-{name}, border-{name} etc. Any --font-* variable becomes available as font-{name}. The naming conventions map predictably from CSS variable names to utility names.
This approach has some real advantages: your design tokens are native CSS custom properties, which means they’re accessible from non-Tailwind CSS, from JavaScript via getComputedStyle, and they work naturally with browser devtools.
The Oxide Engine
Tailwind v4’s engine is a complete rewrite using Rust under the hood (via the @tailwindcss/oxide package) and Lightning CSS for processing instead of PostCSS’s JavaScript-based transforms. The performance difference is substantial:
- Cold build (no cache): ~10x faster than v3 for typical projects
- Incremental build (file change during dev): ~100x faster — essentially instant
- CSS output size: smaller by default because v4 drops utilities you don’t use without any purge configuration
The PostCSS plugin is still available for projects that need it, but the recommended path for new projects and Vite users is the dedicated @tailwindcss/vite plugin, which integrates directly with Vite’s module graph for optimal HMR performance.
Installation and Setup
For a new Vite project:
npm install tailwindcss @tailwindcss/vite
// vite.config.ts
import tailwindcss from '@tailwindcss/vite'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [tailwindcss()]
})
/* src/index.css */
@import "tailwindcss";
That’s it. No tailwind.config.js, no content array, no PostCSS config. The v4 engine auto-detects which files to scan using a heuristic that works correctly for most project structures.
For Next.js 15+, use @tailwindcss/postcss:
npm install tailwindcss @tailwindcss/postcss
// postcss.config.mjs
export default { plugins: { '@tailwindcss/postcss': {} } }
What Changed in the Utility Classes
Most class names are identical to v3. The breaking changes are narrower than they might seem:
Renamed utilities:
shadow-sm→shadow-xs,shadow→shadow-sm(the whole shadow scale shifted down one step)blur-sm→blur-xs,blur→blur-sm(same shift)rounded-sm→rounded-xs,rounded→rounded-smring→ring-3(ring now requires an explicit size)
Removed utilities:
bg-opacity-*,text-opacity-*,border-opacity-*— use opacity modifier syntax instead:bg-black/50overflow-ellipsis→text-ellipsisflex-shrink-*andflex-grow-*→shrink-*andgrow-*(these were already available in v3)
New utilities in v4:
starting:variant for CSS@starting-style(enter animations without JavaScript)field-sizing-contentforfield-sizing: contenton textareasinert:variant targeting theinertHTML attribute- Container queries built in with
@containerand@md:etc. — no plugin required - 3D transform utilities:
rotate-x-*,rotate-y-*,perspective-*
Migrating an Existing Project
The official upgrade tool handles most of the mechanical work:
npx @tailwindcss/upgrade@next
This tool:
- Converts
tailwind.config.jsto@themeblocks in your CSS - Renames deprecated utility classes throughout your templates
- Updates
package.jsondependencies - Migrates
@applydirectives where possible
The upgrade tool doesn’t handle every edge case. Manual review is needed for:
- Custom plugins that used v3’s JavaScript plugin API (the v4 plugin API changed)
- Complex
contentconfiguration using globs or transforms safelistentries (v4 handles this differently via CSS@source)- JIT-mode arbitrary value syntax that relied on v3 internals
After running the tool, do a build and check the output. Most projects come through cleanly; the ones that need manual intervention typically have custom plugins or non-standard configurations.
Custom Plugins in v4
Tailwind v4’s plugin API moved to CSS. Simple utility additions now use @utility:
@utility tab-4 {
tab-size: 4;
}
For variant plugins, use @variant:
@variant hocus (&:hover, &:focus);
JavaScript plugins that used v3’s addUtilities, addComponents, or addVariant APIs need to be ported to the CSS-based equivalents. Many popular plugins (Tailwind Typography, Tailwind Forms) have released v4-compatible versions — check their changelogs before upgrading.
Checking Compatibility
Before migrating a production project, check:
- Framework integration: Next.js 15+, SvelteKit, Nuxt 3, Astro 4+ all have v4 support. Older versions may need their adapter packages updated.
- UI component libraries: If you use a library built on Tailwind (Shadcn/UI, daisyUI, Headless UI), check whether they’ve shipped v4 support. Shadcn/UI updated to v4 in early 2025; daisyUI v5 shipped with v4 support.
- CSS-in-JS: If you’re using Tailwind alongside styled-components or Emotion, the interaction model changed because v4 outputs a single CSS cascade rather than individual utility blocks.
The v4 migration is more work than a typical minor version bump, but teams that have done it report the build speed improvement alone making it worthwhile — particularly for large projects where v3 cold builds were measured in tens of seconds.