Migrate Tailwind CSS v3 configuration to v4 CSS-based config
Migrates Tailwind CSS v3 configuration to v4's CSS-based setup and updates syntax.
/plugin marketplace add gopherguides/gopher-ai/plugin install tailwind@gopher-ai[--check]claude-opus-4-5-20251101If $ARGUMENTS is empty or not provided:
Migrate Tailwind CSS v3 configuration to v4's CSS-based configuration.
Usage: /tailwind-migrate [options]
Examples:
/tailwind-migrate - Migrate v3 to v4/tailwind-migrate --check - Check what would change without modifying filesWhat this command does:
tailwind.config.js or tailwind.config.ts@theme directivecontent paths to @source directives@import "tailwindcss" syntaxKey v4 Changes:
| v3 | v4 |
|---|---|
tailwind.config.js | CSS @theme { } directive |
@tailwind base/components/utilities | @import "tailwindcss" |
darkMode: 'class' | @variant dark { } |
theme.extend.colors | --color-* CSS variables |
Proceed with migration.
If $ARGUMENTS is provided:
Parse arguments:
Look for Tailwind v3 configuration files:
# Check for config files
ls tailwind.config.js tailwind.config.ts tailwind.config.cjs tailwind.config.mjs 2>/dev/null
# Check package.json for Tailwind version
grep '"tailwindcss"' package.json 2>/dev/null
If no config found:
No tailwind.config.* file found.
Options:
1. This project may already be using Tailwind v4 (CSS-based config)
2. Use /tailwind-init to set up Tailwind v4 from scratch
3. Check if config is in a non-standard location
Read and parse the configuration file. Extract:
// v3 tailwind.config.js
module.exports = {
content: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'],
darkMode: 'class',
theme: {
extend: {
colors: {
primary: '#3b82f6',
secondary: '#64748b',
accent: {
light: '#fef3c7',
DEFAULT: '#f59e0b',
dark: '#b45309',
},
},
fontFamily: {
sans: ['Inter', 'sans-serif'],
display: ['Lexend', 'sans-serif'],
},
spacing: {
'18': '4.5rem',
'22': '5.5rem',
},
borderRadius: {
'4xl': '2rem',
},
},
},
plugins: [
require('@tailwindcss/forms'),
require('@tailwindcss/typography'),
],
}
Extract the content array - these become @source directives.
Note any plugins - check v4 compatibility:
| v3 Plugin | v4 Status |
|---|---|
@tailwindcss/forms | Built-in (not needed) |
@tailwindcss/typography | @plugin "@tailwindcss/typography" |
@tailwindcss/container-queries | Built-in (not needed) |
@tailwindcss/aspect-ratio | Built-in (not needed) |
Convert the parsed configuration to v4 CSS syntax:
@import "tailwindcss";
/* Source paths (from content array) */
@source "./src/**/*.{js,jsx,ts,tsx}";
@source "./public/index.html";
/* Theme configuration (from theme.extend) */
@theme {
/* Colors - convert hex to oklch for better manipulation */
--color-primary: oklch(0.59 0.2 250); /* #3b82f6 */
--color-secondary: oklch(0.55 0.02 250); /* #64748b */
--color-accent-light: oklch(0.96 0.05 85); /* #fef3c7 */
--color-accent: oklch(0.75 0.18 70); /* #f59e0b */
--color-accent-dark: oklch(0.52 0.15 50); /* #b45309 */
/* Font families */
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
--font-display: "Lexend", ui-sans-serif, system-ui, sans-serif;
/* Custom spacing */
--spacing-18: 4.5rem;
--spacing-22: 5.5rem;
/* Custom border radius */
--radius-4xl: 2rem;
}
/* Dark mode (from darkMode: 'class') */
@variant dark {
/* Override theme colors for dark mode if needed */
}
/* Plugins */
@plugin "@tailwindcss/typography";
/* Base layer customizations */
@layer base {
html {
font-family: var(--font-sans);
}
}
Convert common hex colors to oklch:
| Hex | oklch | Notes |
|---|---|---|
#3b82f6 (blue-500) | oklch(0.59 0.2 250) | Primary blue |
#ef4444 (red-500) | oklch(0.63 0.26 25) | Error red |
#22c55e (green-500) | oklch(0.72 0.19 145) | Success green |
#f59e0b (amber-500) | oklch(0.75 0.18 70) | Warning amber |
#6366f1 (indigo-500) | oklch(0.58 0.22 275) | Accent indigo |
#ffffff | oklch(1 0 0) | White |
#000000 | oklch(0 0 0) | Black |
Use the oklch color picker: https://oklch.com/
Find CSS files with old directives:
grep -rl '@tailwind' --include="*.css" .
Replace v3 directives:
| v3 | v4 |
|---|---|
@tailwind base; | Remove (included in import) |
@tailwind components; | Remove (included in import) |
@tailwind utilities; | Remove (included in import) |
| All three | @import "tailwindcss"; |
Before:
@tailwind base;
@tailwind components;
@tailwind utilities;
.custom-class {
@apply p-4;
}
After:
@import "tailwindcss";
@source "./src/**/*.{js,jsx}";
@theme {
/* moved from tailwind.config.js */
}
.custom-class {
@apply p-4;
}
Update dependencies based on your integration method:
For CLI method (recommended for most projects):
# Remove old packages
npm uninstall tailwindcss postcss autoprefixer
# Install v4 CLI
npm install -D tailwindcss@latest @tailwindcss/cli@latest
Update scripts:
{
"scripts": {
"css": "npx @tailwindcss/cli -i ./src/input.css -o ./src/output.css --minify",
"css:watch": "npx @tailwindcss/cli -i ./src/input.css -o ./src/output.css --watch"
}
}
For PostCSS method (if using existing PostCSS pipeline):
# Remove old packages but keep postcss
npm uninstall tailwindcss autoprefixer
# Install v4 with PostCSS plugin
npm install -D tailwindcss@latest @tailwindcss/postcss@latest postcss
If project uses PostCSS, update postcss.config.js:
v3:
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
v4:
export default {
plugins: {
'@tailwindcss/postcss': {},
},
}
Note: autoprefixer is no longer needed - v4 handles prefixing automatically.
After successful migration, ask user:
Migration complete. What should we do with tailwind.config.js?
1. Delete it (recommended) - Config is now in CSS
2. Keep it (reference) - Rename to tailwind.config.js.bak
3. Keep it (unchanged) - May cause confusion
Run a test build:
npm run css 2>&1 | head -20
Check for errors. Common issues:
| Error | Solution |
|---|---|
Unknown directive @tailwind | Old directive not removed |
Cannot find module | Plugin not v4 compatible |
Invalid CSS | Syntax error in @theme block |
## Tailwind v3 to v4 Migration Complete
### Changes Made
**Files modified:**
- [CSS file] - Updated directives and added @theme
- package.json - Updated dependencies
- [postcss.config.js] - Updated for v4 (if applicable)
**Configuration migrated:**
- X custom colors → @theme CSS variables
- Y content paths → @source directives
- Z plugins → @plugin directives
- Dark mode → @variant dark
**Files removed:**
- tailwind.config.js (config now in CSS)
### Breaking Changes
[List any potential breaking changes]
### Manual Review Needed
- [ ] Verify custom colors look correct
- [ ] Test dark mode toggle
- [ ] Check responsive breakpoints
- [ ] Verify plugins work correctly
### Next Steps
1. Run `npm run css:watch` to start development
2. Test the application thoroughly
3. Run `/tailwind-audit` to check for any issues
4. Commit changes
### Resources
- Upgrade guide: https://tailwindcss.com/docs/upgrade-guide
- v4 documentation: https://tailwindcss.com/docs
- oklch colors: https://oklch.com/
--check first