Configuration changes
1. PostCSS plugin replaced
v3: tailwindcss PostCSS plugin. v4: @tailwindcss/postcss.
/* postcss.config.mjs */
/* Before */
plugins: { tailwindcss: {} }
/* After */
plugins: { '@tailwindcss/postcss': {} }2. @tailwind directives removed
v3: Three @tailwind directives. v4: Single import statement.
/* Before */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* After */
@import "tailwindcss";3. tailwind.config.js is optional
Tailwind v4 reads theme configuration from CSS via @theme. The JS config file is no longer needed for theming. If you have plugins that require a config, it still works, but the theme section should move to CSS.
4. Content detection is automatic
v4 automatically detects template files. The content array in tailwind.config.js is no longer required for most projects. If you need to explicitly include or exclude paths, use @source in CSS.
/* Explicitly include additional sources */
@source "../node_modules/my-ui-lib/src/**/*.tsx";Visual breaking changes
5. Default border color changed
v3: border defaults to gray-200. v4: border defaults to currentColor.
Impact: Every element with border but no explicit color class will suddenly have dark borders matching the text color.
Fix: Add border-border or border-gray-200 explicitly, or add a global base style:
@layer base {
*, ::after, ::before {
border-color: theme(--color-border, currentColor);
}
}6. Default ring width changed
v3: ring = 3px. v4: ring = 1px.
Fix: Replace ring with ring-3 where you want the old width.
7. Default ring color changed
v3: ring defaults to blue-500 with 50% opacity. v4: ring defaults to currentColor.
Fix: Add ring-ring or ring-blue-500/50 explicitly.
8. Placeholder color opacity
v3: Placeholder text uses the font color at 50% opacity by default. v4: Placeholder text uses currentColor at 50% opacity.
In most cases this looks the same. But if your text color is not a neutral gray, placeholders will be tinted.
9. Outline ring removed
v3: Focus rings used box-shadow. v4: Focus rings use outline.
This means rings now respect border-radius on all browsers (box-shadow rings were always rounded, outline rings weren't until recently). If you were using ring-offset for spacing between the element and ring, use outline-offset instead.
10. Space utilities use gap
v3: space-x-* and space-y-* use > * + * margin selector. v4: Use gap on a flex/grid container.
Impact: Requires parent to be flex or grid. If you used space utilities on non-flex containers, switch to explicit gap or add flex flex-col.
Color system changes
11. Default palette uses OKLCH
All built-in colors (red-500, blue-200, etc.) are now defined in OKLCH instead of hex. The utility class names are the same. The rendered colors are slightly different, especially in the midtones.
Fix: If you need exact v3 hex values, define them explicitly in @theme. Otherwise, the new OKLCH values are generally more consistent.
12. Gradient interpolation
Gradients now interpolate in OKLCH color space by default, producing smoother results. If you need sRGB interpolation to match old designs, specify it explicitly:
background: linear-gradient(in srgb, var(--from), var(--to));Utility changes
13. Shadow utility renamed
v3: shadow applies a default shadow. v4: shadow-sm is the closest equivalent. shadow now applies a slightly larger shadow.
Check any element where you used bare shadow and verify it looks right.
14. Blur utility updated
v3: blur applies 8px. v4: blur applies 8px (unchanged). But blur-sm changed from 4px to 6px, and blur-md from 12px to 10px.
15. Container queries are built in
Remove the @tailwindcss/container-queries plugin. Container queries are now native in v4 using the @container and @sm/@md/@lg syntax.
16. New utility shorthands
v4 adds some new utilities. These don't break anything, but knowing they exist helps:
/* New in v4 */
size-* /* w-* + h-* combined */
inset-* /* top + right + bottom + left */
field-sizing-content /* auto-resize textareas */Plugin and tooling changes
17. Plugin API changed
Third-party plugins written for v3 may not work. Check each plugin for v4 compatibility before upgrading. Common ones affected: typography, forms, container queries (now built in).
18. tailwind-merge needs updating
If you use tailwind-merge (common in shadcn projects via the cn() utility), update to the latest version. Older versions don't recognize v4 utility patterns.
npm install tailwind-merge@latest19. Prettier plugin
Update prettier-plugin-tailwindcss to the latest version for v4 class sorting.
20. VS Code extension
Update the Tailwind CSS IntelliSense extension. Older versions won't recognize @theme directives or provide autocomplete for the new syntax.
The migration order
Go through the checklist in this order to minimize issues:
1. Update packages (Tailwind, PostCSS plugin, tailwind-merge, plugins).
2. Update PostCSS config.
3. Replace @tailwind directives with @import.
4. Move theme config to @theme in CSS.
5. Fix border color defaults (item 5).
6. Fix ring width/color (items 6-7).
7. Test every page visually.
8. Delete tailwind.config.js if empty.
Most migrations take under an hour for a medium-sized project. The breaking changes are well-defined and the fixes are mechanical. For the color system details, see Tailwind v4 Color System. For how design tokens map across config formats, read Tailwind Config Design Tokens. For the CSS variables layer, see CSS Variables vs Tailwind Config vs shadcn Theme. Or skip the manual token migration entirely. SeedFlip exports design tokens in both v3 and v4 formats. Pick a seed, export, paste. Done.