Claude-skill-registry-data migrating-from-v3
Migrate from Tailwind CSS v3 to v4 including configuration migration (JS to CSS), utility renames, opacity changes, and color system updates. Use when upgrading existing projects to v4.
git clone https://github.com/majiayu000/claude-skill-registry-data
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry-data "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/migrating-from-v3" ~/.claude/skills/majiayu000-claude-skill-registry-data-migrating-from-v3 && rm -rf "$T"
data/migrating-from-v3/SKILL.mdMigrating from v3 to v4
Purpose
Migrate existing Tailwind CSS v3 projects to v4's CSS-first configuration, updated utilities, and modern color system.
Automated Migration Tool
Tailwind provides an automated upgrade tool:
npx @tailwindcss/upgrade@next
Requirements:
- Node.js 20 or higher
- Run in a new git branch
- Review all changes manually
- Test thoroughly
What it handles:
- Updates dependencies
- Migrates configuration to CSS
- Updates template files
- Converts utility class names
What it doesn't handle:
- Custom plugins (manual migration needed)
- Complex configuration logic
- Dynamic class generation
Configuration Migration
JavaScript Config → CSS Theme
v3 (tailwind.config.js):
module.exports = { content: ['./src/**/*.{html,js}'], theme: { extend: { colors: { brand: '#3b82f6', accent: '#a855f7', }, fontFamily: { sans: ['Inter', 'sans-serif'], display: ['Satoshi', 'sans-serif'], }, spacing: { 18: '4.5rem', 72: '18rem', }, borderRadius: { '4xl': '2rem', }, }, }, plugins: [], };
v4 (CSS @theme):
@import 'tailwindcss'; @theme { --font-sans: 'Inter', sans-serif; --font-display: 'Satoshi', sans-serif; --color-brand: oklch(0.65 0.25 270); --color-accent: oklch(0.65 0.25 320); --spacing-18: 4.5rem; --spacing-72: 18rem; --radius-4xl: 2rem; }
Content Detection
v3:
content: ['./src/**/*.{html,js,jsx,ts,tsx}']
v4:
Automatic detection. No configuration needed.
Manual control (if needed):
@import 'tailwindcss'; @source "../packages/ui"; @source not "./legacy";
Import Syntax Changes
v3:
@tailwind base; @tailwind components; @tailwind utilities;
v4:
@import 'tailwindcss';
Utility Class Renames
Opacity Modifiers
v3:
<div class="bg-black bg-opacity-50"></div> <div class="text-gray-900 text-opacity-75"></div> <div class="border-blue-500 border-opacity-60"></div>
v4:
<div class="bg-black/50"></div> <div class="text-gray-900/75"></div> <div class="border-blue-500/60"></div>
Migration pattern:
→bg-opacity-{value}bg-{color}/{value}
→text-opacity-{value}text-{color}/{value}
→border-opacity-{value}border-{color}/{value}
Flex Utilities
v3:
<div class="flex-shrink-0"></div> <div class="flex-shrink"></div> <div class="flex-grow-0"></div> <div class="flex-grow"></div>
v4:
<div class="shrink-0"></div> <div class="shrink"></div> <div class="grow-0"></div> <div class="grow"></div>
Migration pattern:
→flex-shrink-*shrink-*
→flex-grow-*grow-*
Shadow Utilities
v3:
<div class="shadow-sm"></div>
v4:
<div class="shadow-xs"></div>
Migration:
→shadow-smshadow-xs- All other shadow utilities remain the same
Ring Width
v3 default:
<input class="ring" />
Ring width: 3px
v4 default:
<input class="ring" />
Ring width: 1px
To keep v3 behavior:
<input class="ring-3" />
Color System Changes
Default Border and Ring Colors
v3:
<div class="border"></div>
Border color: gray-200
v4:
<div class="border"></div>
Border color: currentColor
To keep v3 behavior:
<div class="border border-gray-200"></div>
OkLCh Color Space
v3 (RGB):
colors: { brand: '#3b82f6', }
v4 (OkLCh):
@theme { --color-brand: oklch(0.65 0.25 270); }
Use conversion tool: https://oklch.com/
PostCSS Configuration
Plugin Changes
v3:
module.exports = { plugins: { 'tailwindcss': {}, 'autoprefixer': {}, }, };
v4:
export default { plugins: { '@tailwindcss/postcss': {}, }, };
No longer need
autoprefixer or postcss-import.
Vite Plugin
v3:
import tailwindcss from 'tailwindcss'; import autoprefixer from 'autoprefixer'; export default defineConfig({ css: { postcss: { plugins: [tailwindcss(), autoprefixer()], }, }, });
v4:
import tailwindcss from '@tailwindcss/vite'; export default defineConfig({ plugins: [tailwindcss()], });
Preflight Changes
Placeholder Colors
v3:
Placeholder text: gray-400
v4:
Placeholder text: currentColor at 50% opacity
To keep v3 behavior:
@layer base { ::placeholder { color: theme('colors.gray.400'); } }
Button Cursor
v3:
button { cursor: pointer; }
v4:
button { cursor: default; }
To restore v3 behavior:
@layer base { button { cursor: pointer; } }
Feature Additions
Built-in Container Queries
v3 (plugin required):
plugins: [require('@tailwindcss/container-queries')]
v4 (built-in):
No plugin needed. Use
@container and @{breakpoint}: syntax.
3D Transforms
v3:
Not available
v4:
<div class="transform-3d rotate-x-45 rotate-y-30 translate-z-12"></div>
Starting Variant for Animations
v3:
Not available
v4:
<div class="opacity-100 starting:opacity-0 transition-opacity"></div>
Breaking Changes Checklist
- Update dependencies to v4
- Migrate tailwind.config.js to @theme
- Replace @tailwind directives with @import
- Update PostCSS configuration
- Convert opacity utilities (bg-opacity → bg-{color}/{value})
- Rename flex utilities (flex-shrink → shrink)
- Update shadow-sm to shadow-xs
- Add explicit border colors if using bare
border - Update ring-3 if expecting 3px default
- Convert hex colors to oklch()
- Remove container-queries plugin (now built-in)
- Test placeholder colors
- Test button cursor behavior
- Update arbitrary value syntax (spaces → underscores)
Migration Strategy
Phase 1: Preparation
- Create new git branch
- Ensure all changes committed
- Run automated migration tool
- Review generated changes
Phase 2: Configuration
- Convert tailwind.config.js to CSS @theme
- Update PostCSS/Vite configuration
- Replace @tailwind directives
- Add @source if needed
Phase 3: Utilities
- Search and replace opacity modifiers
- Rename flex utilities
- Update shadow utilities
- Add explicit border colors
- Convert hex colors to oklch()
Phase 4: Testing
- Test all pages/components
- Verify responsive behavior
- Check dark mode
- Test interactive states
- Validate production build
Phase 5: Cleanup
- Remove unused dependencies
- Delete tailwind.config.js
- Update documentation
- Commit changes
Common Issues
Styles Not Applying
Check:
- CSS import:
@import "tailwindcss"; - PostCSS plugin:
@tailwindcss/postcss - Vite plugin:
@tailwindcss/vite - Template files not in .gitignore
Class Names Not Working
Ensure:
- Class names are complete strings
- Not using dynamic concatenation
- Using underscores for spaces in arbitrary values
Colors Look Different
OkLCh uses different color space. Convert hex to oklch using: https://oklch.com/
Build Errors
Check:
- Node.js version (20+)
- Dependencies updated
- PostCSS config using correct plugin
See Also
- references/breaking-changes.md - Complete breaking changes list
- references/migration-checklist.md - Step-by-step migration guide