WebPiki
tutorial

Tailwind CSS v4 Migration: What Changed from v3

Key changes in Tailwind CSS v4 and how to migrate from v3. CSS-based config, new utilities, and the Oxide engine.

New colors painting a style transformation

Tailwind CSS v4 looks similar to v3 on the surface, but the internals changed substantially. The most visible shift: tailwind.config.js is gone. Configuration now lives directly in your CSS file. It feels odd at first, but once you get used to it, it's actually more intuitive.

The Biggest Change — Config Moved to CSS

In v3, you defined colors, fonts, breakpoints, and other design tokens as a JavaScript object in tailwind.config.js. In v4, you define them inside your CSS file using the @theme directive.

/* v3: tailwind.config.js */
/* module.exports = {
  theme: {
    extend: {
      colors: {
        brand: '#3b82f6',
      },
      fontFamily: {
        sans: ['Inter', 'sans-serif'],
      },
    },
  },
} */

/* v4: app.css */
@import "tailwindcss";

@theme {
  --color-brand: #3b82f6;
  --font-sans: 'Inter', sans-serif;
}

You're defining CSS custom properties directly. No JavaScript config file means a simpler build chain, and you can see all your design tokens by just looking at the CSS.

No More content Configuration

The content array was one of the most common sources of frustration in v3. You had to specify which files use Tailwind classes, and forgetting a path meant styles silently didn't apply.

// v3: everyone has gotten bitten by this at least once
module.exports = {
  content: ['./src/**/*.{js,ts,jsx,tsx}'],
}

v4 uses automatic content detection by default. It scans your project directory and finds classes on its own. No content config needed. For some people, this alone is reason enough to migrate.

If you need to exclude or include specific paths, use the @source directive:

@import "tailwindcss";
@source "../node_modules/some-ui-lib";

New Engine — Oxide

v4 runs on a new Rust-based engine called Oxide. What you'll notice:

Build speed — Significantly faster than v3, especially on large projects. Instead of running as a PostCSS plugin, it operates as a standalone CSS processing engine.

Simpler installation — No need to install postcss and autoprefixer separately. One plugin handles everything: @tailwindcss/postcss or @tailwindcss/vite.

# v3
npm install tailwindcss postcss autoprefixer

# v4
npm install tailwindcss @tailwindcss/vite  # Vite projects

Changed Utilities

Color Opacity

<!-- v3 -->
<div class="bg-blue-500/50">

<!-- v4 — same syntax still works, plus CSS variable control -->
<div class="bg-blue-500/50">
<div class="bg-[oklch(0.5_0.2_250/50%)]">

v4 uses the oklch color space internally. You can use oklch values directly, which is useful because oklch is perceptually uniform — maintaining consistent lightness across a color palette becomes much easier.

New Utilities

<!-- Container queries -->
<div class="@container">
  <div class="@lg:flex @md:grid">...</div>
</div>

<!-- 3D transforms -->
<div class="rotate-x-45 perspective-800">

<!-- Gradient improvements -->
<div class="bg-linear-to-r from-blue-500 to-purple-500">
<!-- bg-gradient-to-r → bg-linear-to-r -->

Container queries are now built in. In v3, you needed the @tailwindcss/container-queries plugin. v4 includes them natively. Components can adapt their layout based on their parent's size rather than the viewport — a big deal for reusable components.

Renamed Utilities

Some utilities got more consistent names:

v3v4
bg-gradient-to-rbg-linear-to-r
bg-opacity-50bg-black/50 (already worked in v3)
shadow-smshadow-xs (new size step added)

Most v3 syntax still works, and the automated migration tool handles the renamed ones.

Migration in Practice

1. The Automatic Migration Tool

An official tool is available:

npx @tailwindcss/upgrade

What it does:

  • Converts tailwind.config.js settings to CSS @theme blocks
  • Renames changed utility classes automatically
  • Updates import structure
  • Cleans up PostCSS config

It's not perfect, but it handles the bulk of the conversion. Fix the rest manually.

2. Watch Out For

Plugin compatibility — v3 plugins won't necessarily work in v4. Official plugins like @tailwindcss/typography and @tailwindcss/forms have been updated, but community plugins may need checking.

PostCSS config changes — v4 uses a dedicated plugin (@tailwindcss/postcss or @tailwindcss/vite) instead of the PostCSS plugin approach. Your postcss.config.js needs updating.

Complex JS-based customizations — If you used functions in tailwind.config.js to dynamically generate values, those won't translate 1:1 to CSS @theme. You'll need to combine CSS custom properties with the @utility directive to achieve the same result.

  1. Start from a clean git commit
  2. Run npx @tailwindcss/upgrade
  3. Build and check for errors
  4. Visually inspect pages, fixing broken styles manually
  5. Verify plugin compatibility

For large projects, check page by page rather than trying to verify everything at once.

Should You Migrate?

New projects — start with v4. Simpler config, faster builds, more features.

Existing projects — no rush. v3 will be maintained for a while. But if you want container queries, 3D transforms, or faster builds, there's plenty of reason to migrate. The automated tool makes it a smaller effort than it might seem.

#Tailwind CSS#CSS#Frontend#Migration#Web Development

관련 글