# Tailwind CSS v4 Migration Guide Comprehensive guide for migrating from Tailwind CSS v3 to v4. Tailwind v4 is a ground-up rewrite with CSS-first configuration, new engine, and native support for modern CSS features. ## What Changed: Overview ### Architecture Shift Tailwind v4 replaces JavaScript-based configuration with CSS-first configuration. The `tailwind.config.js` file is no longer required (but supported via compatibility layer). | Concept | v3 | v4 | |---------|----|----| | Config | `tailwind.config.js` (JS) | `@theme {}` block in CSS | | Entry point | `@tailwind base/components/utilities` | `@import "tailwindcss"` | | Plugins | JS `plugin()` API | `@plugin "package"` in CSS | | PostCSS | `tailwindcss` package | `@tailwindcss/postcss` | | Vite | PostCSS plugin | `@tailwindcss/vite` (faster) | | Content detection | `content: [...]` in config | Automatic (scans project) | | Theme values | JS objects | CSS custom properties | | Directives | `@tailwind`, `@screen`, `@variants` | `@import`, `@theme`, `@variant` | ## @theme Directive The `@theme` directive replaces `theme.extend` in `tailwind.config.js`. Values defined here become both CSS custom properties and Tailwind utilities. ### Basic Usage ```css /* v4: CSS-first configuration */ @import "tailwindcss"; @theme { /* Colors: creates bg-brand, text-brand, border-brand, etc. */ --color-brand: #3b82f6; --color-brand-light: #60a5fa; --color-brand-dark: #1d4ed8; /* Semantic colors */ --color-success: #22c55e; --color-warning: #f59e0b; --color-danger: #ef4444; /* Typography */ --font-display: "Inter", "system-ui", sans-serif; --font-body: "Source Sans Pro", "system-ui", sans-serif; --font-mono: "JetBrains Mono", "Fira Code", monospace; /* Custom spacing */ --spacing-18: 4.5rem; --spacing-88: 22rem; --spacing-128: 32rem; /* Custom breakpoints */ --breakpoint-3xl: 1920px; /* Animations */ --animate-fade-in: fade-in 0.3s ease-out; --animate-slide-up: slide-up 0.4s ease-out; } @keyframes fade-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } } @keyframes slide-up { from { opacity: 0; transform: translateY(100%); } to { opacity: 1; transform: translateY(0); } } ``` ### Overriding vs Extending ```css /* EXTENDING: add to existing scale (use --color-* namespace) */ @theme { --color-brand: #3b82f6; /* All default colors (slate, gray, red, etc.) still available */ } /* OVERRIDING: replace entire namespace */ @theme { --color-*: initial; /* Clear all default colors */ --color-primary: #3b82f6; --color-secondary: #6b7280; --color-accent: #f59e0b; /* Only these 3 colors available now */ } ``` ### Accessing Theme Values in CSS ```css /* Theme values are CSS custom properties, usable anywhere */ .custom-element { color: var(--color-brand); font-family: var(--font-display); padding: var(--spacing-18); } ``` ## @config: Compatibility Layer For projects with existing `tailwind.config.js` files, v4 provides a compatibility layer. ```css @import "tailwindcss"; /* Load existing JS config */ @config "./tailwind.config.js"; /* Can combine with @theme (theme overrides config) */ @theme { --color-brand: #3b82f6; } ``` **Migration path**: Start with `@config`, then gradually move values into `@theme`, then remove the JS config. ## @plugin Directive Plugins are now imported directly in CSS. ```css @import "tailwindcss"; /* v4: Import plugins in CSS */ @plugin "@tailwindcss/typography"; @plugin "@tailwindcss/forms"; @plugin "@tailwindcss/container-queries"; /* Local plugin */ @plugin "./plugins/my-custom-plugin.js"; ``` ### Plugin API Changes ```js // v4 plugin API (similar to v3 but with changes) export default function ({ addUtilities, addComponents, matchUtilities, theme }) { addUtilities({ '.content-auto': { 'content-visibility': 'auto' }, '.content-hidden': { 'content-visibility': 'hidden' }, }) } ``` ## New Default Scales ### Spacing v4 uses a simplified spacing scale based on multiples of `0.25rem` (4px). The existing numeric scale (0-96) remains, but new scales are rationalized. ### Colors v4 retains the same color palette names but adds: - OKLCH color support for more perceptually uniform colors - Automatic color opacity via `bg-blue-500/75` (unchanged syntax, improved output) ### Typography ```css @theme { /* v4 uses --text-* for font-size + line-height combos */ --text-base: 1rem; /* 16px */ --text-base--line-height: 1.5rem; /* 24px */ /* Custom text scale */ --text-hero: 4rem; --text-hero--line-height: 1.1; --text-hero--letter-spacing: -0.02em; --text-hero--font-weight: 800; } ``` ## Removed Utilities and Replacements | v3 Utility | Status in v4 | Replacement | |------------|-------------|-------------| | `bg-opacity-*` | Removed | `bg-blue-500/75` (opacity modifier) | | `text-opacity-*` | Removed | `text-blue-500/75` | | `border-opacity-*` | Removed | `border-blue-500/75` | | `divide-opacity-*` | Removed | `divide-blue-500/75` | | `ring-opacity-*` | Removed | `ring-blue-500/75` | | `placeholder-opacity-*` | Removed | `placeholder:text-gray-400/75` | | `flex-shrink` | Renamed | `shrink` (already available in v3) | | `flex-grow` | Renamed | `grow` (already available in v3) | | `overflow-ellipsis` | Renamed | `text-ellipsis` | | `decoration-slice` | Renamed | `box-decoration-slice` | | `decoration-clone` | Renamed | `box-decoration-clone` | ### Opacity Modifier Migration ```html