Blog/Quick Tips & Snippets/Tailwind CSS v4 Migration: What Changed and How to Upgrade
POST
July 20, 2025
LAST UPDATEDJuly 20, 2025

Tailwind CSS v4 Migration: What Changed and How to Upgrade

Step-by-step guide to migrating from Tailwind CSS v3 to v4, covering the new CSS-first config, removed utilities, and breaking changes to fix.

Tags

Tailwind CSSMigrationCSSFrontend
Tailwind CSS v4 Migration: What Changed and How to Upgrade
5 min read

Tailwind CSS v4 Migration: What Changed and How to Upgrade

This is part of the AI Automation Engineer Roadmap series.

TL;DR

Tailwind v4 replaces tailwind.config.js with CSS-first configuration using @theme and @import, drops several deprecated utilities, and ships with a new high-performance Oxide engine.

Why This Matters

Your project uses Tailwind v3 with a JavaScript config file, custom theme values, and plugins. Upgrading to v4 breaks your build because the configuration format has fundamentally changed, and several utility classes you rely on have been renamed or removed.

Tailwind v4 is not just a minor version bump. It changes how configuration works, how the PostCSS pipeline is wired, and how teams think about theme tokens. That means migration quality affects:

  • build stability
  • team conventions
  • design token organization
  • plugin compatibility
  • how much churn lands in one PR

If you approach it as a blind package upgrade, the migration is painful. If you treat it as a controlled refactor, it is much more manageable.

What Actually Changed

The biggest conceptual changes are:

  • CSS-first configuration
  • the new engine and build pipeline
  • utility and syntax cleanup
  • a stronger emphasis on CSS variables and tokens

The migration is easier once you stop thinking in terms of "Tailwind config as a JavaScript object" and start thinking in terms of "design tokens and utilities defined closer to CSS."

Step 1: Run the Automated Upgrade

bash
npx @tailwindcss/upgrade

This codemod handles most renames and config migrations automatically. Review the changes before committing.

Do not treat the codemod as the end of the migration. It gets you through the obvious mechanical changes, but custom theme setup, plugins, and edge-case utilities still need review.

Step 2: Move Config to CSS

css
/* app.css - Before (v3 with JS config) */
@tailwind base;
@tailwind components;
@tailwind utilities;
 
/* app.css - After (v4 CSS-first) */
@import "tailwindcss";
 
@theme {
  --color-brand: #3b82f6;
  --color-brand-dark: #1d4ed8;
  --font-family-heading: "Inter", sans-serif;
  --breakpoint-3xl: 1920px;
}

Custom theme values are now CSS custom properties inside @theme, not JavaScript objects.

This is the change that usually feels the biggest. Teams used to centralizing everything in tailwind.config.js now need to rethink how tokens are organized and where configuration belongs.

Step 3: Update Removed Utilities

html
<!-- v3 (removed) -> v4 (replacement) -->
<!-- bg-opacity-50  -> bg-black/50 -->
<!-- text-opacity-75 -> text-white/75 -->
<!-- flex-grow-0 -> grow-0 -->
<!-- flex-shrink -> shrink -->
<!-- decoration-slice -> box-decoration-slice -->

Utility cleanup is usually straightforward, but it can create a lot of noisy diffs. This is why the migration is better done as a focused branch instead of mixing it with unrelated UI work.

Step 4: Update PostCSS Config

javascript
// postcss.config.js (v4)
export default {
  plugins: {
    "@tailwindcss/postcss": {},
  },
};

The tailwindcss PostCSS plugin is replaced by @tailwindcss/postcss.

Step 5: Audit Custom Plugins and Theme Extensions

This is where many migrations slow down.

Look for:

  • custom plugin functions
  • theme extension helpers
  • arbitrary utility generators
  • assumptions tied to the old config structure

If your setup is heavily customized, the migration is not just package-level. It is a design-system migration.

Step 6: Verify the Real Surfaces

Do not stop at "the build passes." Check the places most likely to break:

  • responsive layouts
  • theme colors
  • typography scales
  • forms
  • dark mode or theme switching
  • components using custom utilities

Tailwind migrations often succeed technically while still breaking visual consistency in subtle ways.

Common Mistakes

Doing the Migration Inside a Large Feature Branch

This makes it much harder to isolate Tailwind-specific regressions.

Assuming the Codemod Solves Everything

It handles a lot of boilerplate, but it does not fully understand your design system or custom conventions.

Forgetting Design Token Semantics

Moving values into @theme is not enough if the token naming is still messy or inconsistent.

Skipping Visual Regression Checks

Tailwind changes can alter spacing, color, or utility output in ways that compile fine but still break the interface.

A Safer Migration Plan

If you are migrating a real product, the safest path is:

  1. upgrade Tailwind in isolation
  2. run the codemod
  3. migrate config into CSS intentionally
  4. clean up removed utilities
  5. audit plugins and custom tokens
  6. run a visual QA pass on core pages

This is slower than doing everything at once, but it reduces the risk of shipping subtle design regressions.

When Not to Upgrade Immediately

If your current v3 setup is stable and heavily customized, upgrading only makes sense when:

  • you want the new CSS-first model
  • you are already touching the design system
  • build performance improvements matter
  • plugin compatibility is confirmed

There is no prize for taking a migration early if the rest of the stack is not ready.

Why This Works

The CSS-first approach means your configuration lives in the same file as your styles, making it portable across frameworks without requiring JavaScript tooling. The @theme directive compiles down to standard CSS custom properties, which browsers understand natively. The Oxide engine, rewritten in Rust, delivers significantly faster builds while maintaining full backward compatibility with v3 utility class names that were not deprecated.

Final Takeaway

Tailwind v4 is a worthwhile migration when approached as a design-system and tooling upgrade, not just a dependency bump. Use the codemod to accelerate the mechanical work, but plan for token cleanup, plugin review, and visual QA before you call it done.

Collaboration

Need help with a project?

Let's Build It

I help startups and established companies design, build, and scale world-class digital products. From deep technical architecture to pixel-perfect UI — let's bring your vision to life.

SH

Article Author

Sadam Hussain

Senior Full Stack Developer

Senior Full Stack Developer with over 7 years of experience building React, Next.js, Node.js, TypeScript, and AI-powered web platforms.

Related Articles

TypeScript Utility Types You Should Know
Feb 10, 20263 min read
TypeScript
Cheatsheet

TypeScript Utility Types You Should Know

Five essential built-in generic utility types in TypeScript that will save you hundreds of lines of code.

Generate Dynamic OG Images in Next.js
Feb 08, 20262 min read
Next.js
OG Images
SEO

Generate Dynamic OG Images in Next.js

Generate dynamic Open Graph images in Next.js using the ImageResponse API with custom fonts, gradients, and data-driven content for social sharing.

GitHub Actions Reusable Workflows: Stop Repeating Yourself
Jan 22, 20263 min read
GitHub Actions
CI/CD
DevOps

GitHub Actions Reusable Workflows: Stop Repeating Yourself

Create reusable GitHub Actions workflows with inputs, secrets, and outputs to eliminate YAML duplication across repositories and teams efficiently.