---
name: tailwind-v4-oxide-css
description: "Migrate v3 to Tailwind v4 Oxide, author CSS-first @theme tokens, wire the Vite/PostCSS plugin, ship shadcn variants. Production Tailwind v4: CSS-first config with @theme tokens, @import \"tailwindcss\" replacing the three @tailwind directives, @plugin and @utility for custom utilities, and @custom-variant for dark mode. Wires @tailwindcss/vite or @tailwindcss/postcss, runs npx @tailwindcss/upgrade, and rebuilds shadcn/ui on oklch CSS variables. Covers v3-to-v4 breaking changes: renamed shadow/blur/radius scales, default ring width, space-between selector, and dropped tailwind.config.js."
license: MIT
---

# Tailwind v4 Migrator

Move a Tailwind CSS v3 codebase to the v4 Oxide engine without leaving broken classes or a stale config behind. This skill runs the official upgrade tool, rewrites your CSS entry to the CSS-first model, swaps in the right build plugin for your bundler, and repairs shadcn/ui setups that assumed `tailwind.config.js`. It is aimed at frontend engineers maintaining real apps on Vite, Next.js, or a PostCSS pipeline.

## When to use it

- You have a working v3 project and want the faster Oxide engine plus native cascade-layer output.
- `npx @tailwindcss/upgrade` ran but left `@apply` errors, missing CSS variables, or a `tailwind.config.js` that nothing reads anymore.
- Your shadcn/ui components stopped theming correctly after the bump (the `hsl(var(--...))` token plumbing changed).
- You are starting fresh on v4 and want a clean `@theme` block instead of porting a JS config.

## What it does

- Runs `npx @tailwindcss/upgrade` (the codemod that rewrites utility class renames like `shadow-sm` → `shadow-xs` and `outline-none` → `outline-hidden`).
- Replaces the three `@tailwind base; @tailwind components; @tailwind utilities;` directives with a single `@import "tailwindcss";`.
- Translates `theme.extend` values into a CSS-first `@theme { --color-*, --font-*, --spacing-* }` block so tokens become real custom properties.
- Wires the build: `@tailwindcss/vite` in `vite.config.ts`, or `@tailwindcss/postcss` in `postcss.config.mjs` for Next.js/Webpack. Removes the old `tailwindcss` + `autoprefixer` PostCSS entries (v4 handles prefixing).
- Ports custom utilities to `@utility`, plugins to `@plugin`, and converts dark mode to `@custom-variant dark (&:where(.dark, .dark *));`.

## Usage

```bash
curl -fsSL --create-dirs -o ~/.claude/skills/tailwind-v4-oxide-css/SKILL.md https://claudeskil.com/skills/tailwind-v4-oxide-css/SKILL.md
# then, in your project:
claude "migrate this app to Tailwind v4"
```

Resulting CSS entry:

```css
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));

@theme {
  --color-brand: oklch(0.62 0.19 256);
  --font-display: "Inter", sans-serif;
}

@utility tap-highlight-none {
  -webkit-tap-highlight-color: transparent;
}
```

## Tips & gotchas

- v4 needs a modern target (Safari 16.4+, Chrome 111+); it emits `oklch()` and `@property`. Don't migrate if you must support older browsers.
- `@theme` keys are namespaced — `--color-brand` generates `bg-brand`/`text-brand` automatically. Arbitrary CSS vars under `:root` do **not** create utilities; only `@theme` does.
- Keep `@import` lines first. Anything before `@import "tailwindcss";` breaks the cascade-layer ordering silently.
- For shadcn, regenerate `components.json`-driven tokens; the v3 `hsl(var(--background))` pattern still works but new components expect the v4 layout.

## FAQ

**Do I still need a JS config?** No. `@config "./tailwind.config.js";` is supported for gradual migration, but the target is a fully CSS-first setup with no JS config.

**Is autoprefixer still required?** No. Oxide includes vendor prefixing and `@import` inlining, so you remove both `autoprefixer` and `postcss-import`.

**Will the codemod touch my components?** It rewrites renamed utility classes in your templates and CSS. Review the diff — custom class strings built at runtime won't be caught.
