Migrating to Tailwind CSS 4.0 in Next.js Projects
Step-by-step guide to migrating from Tailwind CSS 3.x to 4.0 in Next.js with App Router
Migrating to Tailwind CSS 4.0 in Next.js Projects
Introduction
Tailwind CSS 4.0 is a major release that changes how the framework is configured and compiled. The new Oxide engine provides significantly faster build times, but the migration from 3.x requires attention to configuration changes, new features, and deprecated utilities.
After migrating a production Next.js 14 application from Tailwind 3.4 to 4.0, I documented every breaking change and optimization opportunity. The build time improvement was dramatic: from 4.2 seconds to 0.8 seconds for a 500-component project.
Environment
- OS: Windows 11
- Node.js: v20.10.0
- Next.js: 14.0.4
- Tailwind CSS: 3.4.1 to 4.0.0
- PostCSS: 8.4.32
Problem
After updating to Tailwind CSS 4.0, several issues occurred:
Error: PostCSS plugin "tailwindcss" requires Tailwind CSS 3.xWarning: Unknown utility class "text-balance"Error: Cannot resolve module "tailwindcss/theme"The configuration file format changed completely between versions.
Solution
Step 1: Update dependencies
# Remove old dependencies
npm uninstall tailwindcss postcss autoprefixer @tailwindcss/typography
# Install Tailwind CSS 4.0
npm install tailwindcss@latest @tailwindcss/postcss@latest
# For Next.js integration
npm install @tailwindcss/postcssStep 2: Update PostCSS configuration
// postcss.config.js (Tailwind 4.0)
module.exports = {
plugins: {
'@tailwindcss/postcss': {},
},
}Step 3: Migrate CSS configuration
/* app/globals.css (Tailwind 4.0) */
@import "tailwindcss";
/* Custom theme configuration */
@theme {
--color-primary: #3b82f6;
--color-secondary: #64748b;
--color-accent: #f59e0b;
--font-sans: 'Inter', system-ui, sans-serif;
--font-mono: 'Fira Code', monospace;
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 1.5rem;
--spacing-xl: 2rem;
}
/* Custom utilities */
@utility container {
margin-inline: auto;
padding-inline: 1rem;
max-width: 1200px;
}
/* Dark mode */
@variant dark (&:where(.dark, .dark *));Step 4: Update component classes
// Before (Tailwind 3.x)
// After (Tailwind 4.0) - Most classes remain the same
// New text balance utility
Title
// New color-mix based opacity
Step 5: Migrate custom plugins
// tailwind.config.js (OLD - Tailwind 3.x)
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addUtilities }) {
addUtilities({
'.text-shadow': {
textShadow: '0 2px 4px rgba(0,0,0,0.1)',
},
})
}),
],
}
/* app/globals.css (NEW - Tailwind 4.0) */
@utility text-shadow {
text-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
@utility text-shadow-lg {
text-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
Step 6: Handle deprecated utilities
// Deprecated in 4.0 - Use new alternatives
// OLD: bg-opacity-50
// NEW: bg-primary/50
// OLD: text-opacity-75
// NEW: text-primary/75
// OLD: border-opacity-25
// NEW: border-primary/25
// OLD: ring-opacity-50
// NEW: ring-primary/50
Lessons Learned
Delete tailwind.config.js after migration. Tailwind 4.0 uses CSS-based configuration exclusively. Keeping the old config file causes conflicts.
Use the official migration tool. Run npx @tailwindcss/upgrade to automatically convert most configuration and class names.
Test every page after migration. Subtle class name changes can cause layout shifts that are not immediately obvious.
Benefit from automatic content detection. Tailwind 4.0 automatically detects source files, eliminating the content array in configuration.
Leverage the new Oxide engine. The build time improvement is significant. If you are still on 3.x, upgrading is worth the migration effort.
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.