Skip to main content
All articles
Guide July 15, 2026 8 min read

Migrating to Tailwind CSS v4: A Practical Guide

Tailwind CSS v4 is a significant rewrite. Here's what changes, what breaks, and how to migrate your project step by step — from config file to CSS-first.

By Ninna UI Team


Tailwind CSS v4 is a ground-up rewrite that moves configuration from JavaScript to CSS. If you're on v3, migrating is straightforward but requires understanding what changed. This guide walks through it step by step.

1. Install the Vite plugin

Tailwind v4 replaces the PostCSS plugin with a Vite plugin (or a standalone CLI). If you're using Vite:

npm install tailwindcss@latest @tailwindcss/vite@latest
npm uninstall @tailwindcss/postcss postcss autoprefixer
// vite.config.ts
import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
  plugins: [react(), tailwindcss()],
});

2. Replace your CSS entry

In v3, your CSS entry had @tailwind directives. In v4, it's a single @import:

/* Before (v3) */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* After (v4) */
@import "tailwindcss";

3. Remove tailwind.config.ts

In v4, configuration lives in CSS via @theme. Move your custom colors, fonts, and breakpoints:

/* Before (v3): tailwind.config.ts */
module.exports = {
  theme: {
    extend: {
      colors: { brand: "#3b82f6" },
    },
  },
};

/* After (v4): in your CSS */
@theme {
  --color-brand: oklch(0.55 0.22 260);
}

4. Update dark mode

In v3, dark mode used the darkMode: 'class' config. In v4, use the @variant directive:

/* Enable class-based dark mode in v4 */
@variant dark (&:is(.dark *));

5. Check @apply usage

@apply still works in v4, but some utility names changed. The most common: bg-opacity-* is now bg-*/opacity, text-opacity-* is now text-*/opacity. Run the build and fix any errors.

6. Update content paths

In v3, you specified content paths in the config file. In v4, Tailwind automatically scans your project. If you have files outside the default scan paths, use @source:

@source "../node_modules/@ninna-ui/*/dist/**/*.js";

If you're using Ninna UI, the @source directive for safelisting classes from node_modules is already handled by the @ninna-ui/core package's safelist system. You just need @import for the theme preset.

What you gain

  • Faster builds — the new engine is significantly faster
  • No config file — everything is CSS
  • oklch colors — better color system by default
  • Smaller output — the compiler is more aggressive about purging
  • Native CSS variables — theme tokens are real CSS custom properties

Build it with Ninna UI

Accessible React components, CSS-only theming, Tailwind v4 native.

Get Started

Keep reading