Migrating to Tailwind CSS v4: What Broke and What Improved

I recently migrated three separate projects from Tailwind CSS v3 to v4. Each project had different challenges, but the patterns were consistent. Here's what I learned so you don't hit the same walls.

Run the Upgrade Tool First

Before doing anything manually, run the official migration tool:

Terminal

This handles the majority of breaking changes automatically. Across my three projects, it caught about 80% of what needed to change. The remaining 20% required manual work.

The Big Change: CSS-First Config

In v3, your config lived in tailwind.config.js:

JavaScript

In v4, it moves to your CSS file:

CSS

This feels more natural. Your styles are defined where styles belong — in CSS.

What Broke

1. Custom Color Definitions

v3 color syntax doesn't map 1:1 to v4. If you were using color functions or opacity modifiers with custom colors, you'll need to update them:

CSS

Using oklch for color definitions gives you better opacity modifier support in v4.

2. Container Queries

v3 required the @tailwindcss/container-queries plugin. In v4, it's built-in:

HTML

3. Some Utility Renames

A few utilities were renamed or consolidated:

  • shadow-sm behavior changed slightly
  • ring utilities have new defaults
  • New inset-shadow-* and inset-ring-* utilities

The upgrade tool catches most of these, but review your components visually after migration.

Before and After Tailwind v4 Migration

What Improved

Performance

The new Rust-based Oxide engine is dramatically faster. In kit, which has 150+ React components, the full build went from ~4 seconds to under 500ms. Incremental rebuilds during development are nearly instant.

No Content Configuration

v4 automatically detects your template files. No more maintaining a content array:

JavaScript

The size-* Utility

Setting width and height together is something I do constantly:

HTML

Small, but it adds up across a codebase.

Migration Tips

  1. Run the upgrade tool first — Don't try to migrate manually
  2. Check your custom theme values — They need to move from JS to CSS @theme blocks
  3. Test dark mode — The dark mode implementation changed slightly
  4. Review shadows and rings — These had the most subtle breaking changes
  5. Remove the content config — v4 handles this automatically
  6. Delete tailwind.config.js — Once migration is complete, you don't need it

Was It Worth It?

Absolutely. The build performance alone justified the migration. The CSS-first config is cleaner. The new utilities (size-*, built-in container queries) reduce class count. And not having to maintain content paths removes a common source of "why isn't my class working?" bugs.

If you're starting a new project, use v4. If you're on v3, the migration is smoother than you'd expect — especially with the upgrade tool doing the heavy lifting.

Related articles