Skip to main content
The @tailwindcss/upgrade package provides automated codemods to migrate your Tailwind CSS project from v3 to v4. It handles CSS files, JavaScript configuration, and template files.

Installation

You don’t need to install the upgrade tool. Run it directly with npx:
Important: The upgrade tool requires a clean git working directory. Commit or stash your changes before running.

Basic usage

Navigate to your project root and run:
The tool will:
  1. Verify your git directory is clean
  2. Check your Tailwind CSS version
  3. Discover and migrate CSS files
  4. Convert JavaScript configuration to CSS
  5. Update template files with new class names
  6. Update dependencies to v4
  7. Migrate PostCSS configuration if needed

Command-line options

Specify CSS files

By default, the tool discovers CSS files automatically. To specify specific files:
Multiple files:

Force migration

Bypass the git clean check (not recommended):

Custom config path

Specify a custom Tailwind configuration file:

Show help

Display usage information:

Show version

Display the tool version:

What gets migrated

CSS file migrations

The tool performs these CSS transformations:

Tailwind directives

Before:
After:

Custom imports

Before:
After:

Layer utilities

Before:
After:

Apply statements

Before:
After:
Note: Class names in @apply are updated to v4 syntax.

Media screen queries

Before:
After:

JavaScript config migrations

The tool converts your tailwind.config.js to CSS:

Theme customization

Before:
After:

Container configuration

Before:
After:

Dark mode

Before:
After:

Custom variants

Before:
After:

Data/aria variants

Before:
After:

Template file migrations

The tool updates class names in all your template files:

Class name updates

Before:
After:

Arbitrary values to named values

The tool converts arbitrary values to named values where possible: Before:
After:

Variant order

Class variants are canonicalized to the correct order: Before:
After:

Group variants

Some group/peer patterns are updated: Before:
After:

Modifier shorthand

Modifiers are converted to the new syntax: Before:
After:

Dependency updates

The tool updates these packages to their latest versions:
Only packages already in your package.json are updated.

PostCSS config migration

For PostCSS-based projects: Before:
After:
Note: Autoprefixer is removed as it’s now built into Tailwind CSS v4.

File discovery

The upgrade tool automatically discovers files to migrate:

CSS files

Searches for **/*.css files while:
  • Respecting .gitignore rules
  • Skipping node_modules
  • Only processing files containing Tailwind directives

Template files

Scans files based on your @source directives or discovers automatically:
  • JavaScript: .js, .jsx, .ts, .tsx
  • Vue: .vue
  • Svelte: .svelte
  • HTML: .html, .htm
  • PHP: .php
  • Ruby: .erb, .haml, .slim
  • And more…

Ignored files

These are automatically skipped:
  • node_modules/
  • .git/
  • .next/
  • .turbo/
  • .vercel/
  • .pnpm-store/
  • Binary files (.png, .jpg, .wasm, .node, etc.)
  • Log files (.log)
  • Database files (.db, .sqlite)

Migration strategies

The tool uses several strategies to ensure safe migrations:

Safe migration checks

Before migrating a class, the tool verifies:
  1. Not in a code comment - Skips migrations in comments
  2. Not in a string literal - Avoids changing unrelated strings
  3. Not in event handlers - Preserves JavaScript like addEventListener('blur', ...)
  4. Valid in context - Ensures the migration makes sense
Example of what’s NOT migrated:

Canonicalization

Classes are canonicalized to their preferred form:
  • Variants in the correct order
  • Arbitrary values simplified where possible
  • CSS variable syntax updated
  • Modifiers in standard format

Caching

The tool caches migration results for performance:
  • Each unique class is processed once
  • Results are reused across all files
  • Significantly speeds up large projects

Handling edge cases

Multiple config files

For monorepos or projects with multiple configs:
The tool handles:
  • Multiple CSS entry points
  • Shared configuration files
  • Workspace dependencies

Dynamic class generation

Some dynamic classes can’t be migrated automatically:
For dynamic classes:
  1. Review the migration output
  2. Manually update dynamic class generation
  3. Use a linter to catch issues

Template syntax

The tool understands various template syntaxes: Vue:
React:
Angular:

Preserving formatting

The tool attempts to preserve:
  • Indentation
  • Line breaks
  • Code style
  • Comments
CSS files are formatted using Prettier after migration for consistency.

After migration

Review changes

Always review the changes made:
Look for:
  • Unexpected class changes
  • Configuration that wasn’t migrated
  • Template files that need manual updates

Test your build

Run your build to catch any issues:
Common issues:
  • Missing dependencies
  • Plugin compatibility
  • Custom configuration that needs manual migration

Visual testing

Perform visual regression testing:
  • Check that UI looks correct
  • Verify dark mode still works
  • Test responsive breakpoints
  • Validate animations and transitions

Commit changes

Once verified, commit the migration:

Troubleshooting

Tool crashes

If the upgrade tool crashes:

Version mismatch

Solution:

Config not migrating

Some configs require manual migration:
  • Complex plugin functions
  • Dynamic theme values
  • Custom match variants with complex logic
Check the output for warnings about unmigrated config.

Classes not updating

If classes aren’t migrated:
  1. Check file extension - Ensure the file type is recognized
  2. Check .gitignore - File might be ignored
  3. Check syntax - Dynamic classes won’t migrate
  4. Run manually - Specify the file explicitly

Build errors after migration

If you get build errors:
  1. Clear build cache:
  2. Reinstall dependencies:
  3. Check for plugin updates:
    • Ensure third-party plugins support v4
    • Update or remove incompatible plugins

Advanced usage

Incremental migration

For large projects, migrate incrementally:

Custom migrations

For custom migrations beyond what the tool provides:
  1. Use the tool for standard migrations
  2. Write custom scripts for project-specific patterns
  3. Use find/replace for bulk updates
  4. Leverage editor regex capabilities

Monorepo migration

For monorepos:
Or from the root:

Limitations

What’s NOT migrated automatically

The following require manual migration:
  1. Complex JavaScript plugins - Custom plugin logic
  2. Dynamic class generation - Runtime-generated classes
  3. Some theme functions - Complex theme() usage
  4. Custom CSS-in-JS - Styled-components, Emotion, etc.
  5. Build scripts - Custom build configurations
  6. Third-party plugins - May need updates from maintainers

Framework-specific considerations

Next.js:
  • App Router vs Pages Router differences
  • Server Components considerations
  • Image optimization integration
Remix:
  • Route-based styles
  • PostCSS integration
SvelteKit:
  • Scoped styles in components
  • Vite plugin integration

Migration checklist

Use this to track your migration:
  • Backup project or commit all changes
  • Run npx @tailwindcss/upgrade
  • Review git diff for all changes
  • Test build process
  • Visual regression testing
  • Update custom plugins if needed
  • Check dark mode implementation
  • Verify responsive design
  • Test in all target browsers
  • Update documentation
  • Commit the migration

Getting help

If you need assistance: