Migrate a project from Tailwind CSS v3 to v4 safely and completely. Runs the official `@tailwindcss/upgrade` codemod, then drives the judgment it can't: reconciling dependencies and PostCSS/Vite/CLI plumbing, porting JS config to CSS-first `@theme` (or keeping it via `@config`), auditing the v4 changed-defaults that silently alter appearance (border/ring/placeholder/cursor/dialog/hover) and applying compat shims, sweeping for renamed/removed utilities, and proving the migration is a visual no-op. Framework-agnostic (Next.js, Vite, Tailwind CLI, plain PostCSS; Vue/Svelte/Astro/CSS-module caveats). USE FOR: upgrading Tailwind 3 to 4, "tailwind v4 migration", `@tailwind` directives error, `@tailwindcss/postcss` setup, tailwind.config.js to CSS @theme, shadow-sm/rounded/ring/outline-none renames, bg-gradient-to to bg-linear-to. Activate only when an existing Tailwind v3 install is being upgraded. DO NOT USE FOR: a fresh v4 setup with no v3 present, downgrading v4 to v3, or non-Tailwind CSS.
Upgrade a codebase from Tailwind CSS v3 to v4. The codemod does ~80% of the mechanical work; this
skill supplies the 20% of judgment where migrations actually break — changed defaults, config
porting, plugin/animation swaps, and proving nothing moved.
When to use
Upgrading any project from Tailwind v3.x to v4.x.
Build errors after a partial upgrade: @tailwind directives unknown, missing @tailwindcss/postcss,
Cannot apply unknown utility class, tailwind.config no longer picked up.
Converting tailwind.config.{js,ts} to CSS-first @theme.
Skip if: the project is already on v4; you need to downgrade; or you are building a brand-new design
system rather than migrating one. Note v4 targets Safari 16.4+, Chrome 111+, Firefox 128+ —
if you must support older browsers, stay on v3.4 (flag this to the operator before proceeding).
The one idea that makes this safe
A correct migration is a visual no-op. Every renamed utility is a pure alias — shadow-sm→
shadow-xs, rounded→rounded-sm, ring→ring-3, outline-none→outline-hidden all compile to
the same CSS as before. So what changes pixels is almost entirely v4's changed defaults (Step 3);
the few non-default exceptions — the space-x/y-* & divide-* selector change, gradient-variant
preservation, and container config removal — are flagged in Step 4. Rename mechanically, neutralize
the changed defaults, fix those few exceptions, and the rendered output is identical. That is also how
you verify success (Step 5): capture the UI before, prove it's unchanged after.
Procedure
Always work on a branch. Run the steps in order; do not skip Step 0 or Step 3.
Step 0 — Pre-flight & baseline (do not skip)
Confirm Node 20+ (node -v) and that the working tree is clean. Create a branch (e.g. tailwind-v4).
Inventory every Tailwind entry point — there may be more than one: each CSS file with
@tailwind/@import "tailwindcss", every tailwind.config.*, every postcss.config.*, the
bundler config (next/vite/webpack), and package.json. Monorepos: do this per package.
Record the current setup: darkMode value, custom theme.extend, plugins, the package
manager (npm/yarn/pnpm/bun), and two easy-to-miss config options that need special handling later:
prefix (v4 changes tw-flex→tw:flex) and theme.container (center/padding are gone
in v4 — recreate via @utility container).
Capture a baseline of how the app looks now so you can prove the migration changed nothing:
a screenshot set or a visual-regression run on v3 (see references/05-verification-playwright.md),
or at minimum a list of key pages to eyeball. Confirm the project builds green on v3 first.
Step 1 — Run the official upgrade tool
npx @tailwindcss/upgrade@latest # clean git tree required…
npx @tailwindcss/upgrade@latest --force # …or pass --force if untracked/uncommitted files exist
The tool refuses to run on a dirty tree (so you can review its diff). Commit/stash unrelated changes,
or use --force. It updates dependencies, migrates the config to CSS where it can, rewrites
@tailwind directives, and codemods most renamed/removed utilities in templates. Review the full
diff — it is a starting point, not the finish line. If it errors (offline, exotic setup, unsupported
config), fall back to the manual path in references/01-breaking-changes.md +
references/02-css-first-config.md and continue. Monorepos: run the tool once per package root and
confirm tailwindcss resolves to 4.x in every package's node_modules — a half-migrated workspace
compiles some packages against v3.
Step 2 — Reconcile dependencies & build plumbing
Verify the tool did these; finish any it missed (references/04-framework-setups.md for your stack):
Deps: remove tailwindcss@3; add tailwindcss@^4. Remove autoprefixer and postcss-import
(v4 does prefixing + import inlining itself).
Plugins: delete now-built-in ones (@tailwindcss/container-queries, @tailwindcss/aspect-ratio,
line-clamp) — and remove their dead theme/usage. @tailwindcss/typography stays but is loaded
in CSS via @plugin "@tailwindcss/typography"; and must be bumped to a v4-compatible release (≥0.5.16).
container customization: if v3 set theme.container.center/padding, those options are gone —
recreate as @utility container { margin-inline: auto; padding-inline: 2rem; } or every container
loses its centering/padding silently.
Reinstall with the project's package manager so the lockfile updates; the tailwindcss version must
resolve to 4.x.
These changed defaults are the main thing that moves pixels (see Step 4 for the few non-default
exceptions). Walk the checklist; for each "relied on", paste the shim into your main CSS (after
@import "tailwindcss";). Full rationale in references/03-compat-shims.md.
Border/divide color is now currentColor (was gray-200). If you use bare border/divide
without a color anywhere, add:
Ring is now 1px / currentColor (was 3px / blue-500). Replace bare ring→ring-3; if you
relied on the blue default add ring-blue-500. (Compat-only escape: @theme { --default-ring-width: 3px; --default-ring-color: var(--color-blue-500); }.)
Placeholder is now current text @ 50% (was gray-400). To keep v3 look:
@layer base { input::placeholder, textarea::placeholder { color: var(--color-gray-400); } }
Buttons now use cursor: default (was pointer):
@layer base { button:not(:disabled), [role="button"]:not(:disabled) { cursor: pointer; } }
<dialog> margins are reset (was centered): @layer base { dialog { margin: auto; } } if needed.
Hover now applies only on (hover: hover) devices. If your UI depends on tap-to-hover, add
@custom-variant hover (&:hover);.
Dark mode: if v3 used darkMode: 'class' (or a custom selector), add
@custom-variant dark (&:is(.dark, .dark *));. If it used 'media', v4's default already matches —
do nothing (adding the class variant would break media-driven dark mode).
Two of these are invisible to a screenshot harness: the button-cursor and hover-on-tap
shims change behavior, not painted pixels, so visual parity (Step 5) can't confirm them. Decide them
by reasoning about the markup (do real <button>s / touch interactions rely on the v3 default?), not
by the pixel diff. Same for outline-none→outline-hidden (the difference only shows in forced-colors mode).
Step 4 — Residual sweep (catch what the codemod missed)
Grep, then fix each real hit against the tables in references/01-breaking-changes.md (which cover the
mechanical rewrites: *-opacity-*→/<n>, flex-shrink/grow→shrink/grow, bg-gradient-to→
bg-linear-to, arbitrary bg-[--x]→bg-(--x), !flex→flex!, theme()→var(--…), etc.):
grep -rEn '@tailwind |bg-gradient-to-|flex-shrink-|flex-grow-|overflow-ellipsis|decoration-slice|decoration-clone|[a-z]+-opacity-[0-9]|outline-none' src
grep -rEn '\b(shadow|rounded|blur|drop-shadow|backdrop-blur)(["'"'"'`[:space:]])' src # bare scales — review, don't blind-replace
grep -rEn 'transition(-colors)?\b' src # if paired with a focus-state outline-* color → set outline-color unconditionally
# only if v3 used a prefix (Step 0): grep -rEn '\bPFX-[a-z]' src # PFX-flex → PFX:flex
Three judgment calls the tables don't make for you:
Order bare renames after explicit ones:shadow-sm→shadow-xsbefore bare shadow→shadow-sm
(same for rounded/blur/drop-shadow/backdrop-blur); word-boundary the bare form so rounded-md/
shadow-lg are untouched. The grep is noisy — blur/shadow collide with placeholder="blur" and
prose; fix only real class lists.
space-x/y-* & divide-x/y-* selectors changed to :not(:last-child) (no shim). If a list/inline
layout shifts, move it to flex/grid + gap.
Gradients now preserve stops across variants — add via-none to reset a 3-stop in a state.
Step 5 — Verify (build + browser parity)
build, lint, typecheck, and unit tests must pass.
Prove the visual no-op: re-run the baseline from Step 0 and confirm zero unintended diffs. Pay
special attention to: borders, focus rings, placeholders, dark mode, and any prose (typography)
content. Any diff maps to a missed Step 3 shim or Step 4 rename — fix it, don't accept it.
Check the screenshot-invisible changes by hand: button cursor, hover-on-touch, and forced-colors
outline behavior (see the Step 3 note) — confirm these in a real browser, since no pixel diff will.
Decision points
Port JS config to CSS, or keep it? Default: port theme.extend to a CSS @theme {} block
(nested objects → flat vars: colors.brand.500→--color-brand-500, boxShadow.card→--shadow-card,
fontFamily.sans→--font-sans; use @theme inline for hsl(var(--x)) references). Keep the JS
file via @config "../tailwind.config.js"; when it carries plugin theming that's hard to express in
CSS — the classic case is @tailwindcss/typographytheme.extend.typography customization
(custom prose-* modifiers). @config is officially supported v4 usage. corePlugins, safelist,
separator are NOT supported in JS config under v4 (safelist → @source inline(...)). Note:
Tailwind's default theme tokens (e.g. --color-gray-200, --color-gray-400) stay available even
when you keep a JS config via @config, so the Step 3 compat shims that reference them still resolve.
See references/02-css-first-config.md.
CSS directive order:@import "tailwindcss"; must come first; place @config "…"; and any
@theme { … } block after it.
Custom @layer utilities/@layer components classes → convert to @utility name { … }.
Scoped styles (Vue/Svelte/Astro <style>, CSS modules) lose theme access → add
@reference "../app.css"; or use raw CSS vars. No Sass/Less/Stylus with v4.
1---2name: tailwind-v3-to-v4-migration3description: Migrate a project from Tailwind CSS v3 to v4 safely and completely. Runs the official `@tailwindcss/upgrade` codemod, then drives the judgment it can't: reconciling dependencies and PostCSS/Vite/CLI plumbing, porting JS config to CSS-first `@theme` (or keeping it via `@config`), auditing the v4 changed-defaults that silently alter appearance (border/ring/placeholder/cursor/dialog/hover) and applying compat shims, sweeping for renamed/removed utilities, and proving the migration is a visual no-op. Framework-agnostic (Next.js, Vite, Tailwind CLI, plain PostCSS; Vue/Svelte/Astro/CSS-module caveats). USE FOR: upgrading Tailwind 3 to 4, "tailwind v4 migration", `@tailwind` directives error, `@tailwindcss/postcss` setup, tailwind.config.js to CSS @theme, shadow-sm/rounded/ring/outline-none renames, bg-gradient-to to bg-linear-to. Activate only when an existing Tailwind v3 install is being upgraded. DO NOT USE FOR: a fresh v4 setup with no v3 present, downgrading v4 to v3, or non-Tailwind CSS.4license: MIT5---67# tailwind-v3-to-v4-migration
89Upgrade a codebase from Tailwind CSS v3 to v4. The codemod does ~80% of the mechanical work; this
10skill supplies the 20% of judgment where migrations actually break — changed defaults, config
11porting, plugin/animation swaps, and proving nothing moved.
1213## When to use
1415- Upgrading any project from Tailwind v3.x to v4.x.
16- Build errors after a partial upgrade: `@tailwind` directives unknown, missing `@tailwindcss/postcss`,
17 `Cannot apply unknown utility class`, `tailwind.config` no longer picked up.
18- Converting `tailwind.config.{js,ts}` to CSS-first `@theme`.
1920Skip if: the project is already on v4; you need to *downgrade*; or you are building a brand-new design
21system rather than migrating one. Note v4 targets **Safari 16.4+, Chrome 111+, Firefox 128+** —
22if you must support older browsers, stay on v3.4 (flag this to the operator before proceeding).
2324## The one idea that makes this safe
2526**A correct migration is a visual no-op.** Every renamed utility is a pure alias — `shadow-sm`→
27`shadow-xs`, `rounded`→`rounded-sm`, `ring`→`ring-3`, `outline-none`→`outline-hidden` all compile to
28the *same* CSS as before. So what changes pixels is almost entirely v4's **changed defaults** (Step 3);
29the few non-default exceptions — the `space-x/y-*` & `divide-*` selector change, gradient-variant
30preservation, and `container` config removal — are flagged in Step 4. Rename mechanically, neutralize
31the changed defaults, fix those few exceptions, and the rendered output is identical. That is also how
32you verify success (Step 5): capture the UI before, prove it's unchanged after.
3334## Procedure
3536Always work on a branch. Run the steps in order; do not skip Step 0 or Step 3.
3738### Step 0 — Pre-flight & baseline (do not skip)
39401. Confirm Node 20+ (`node -v`) and that the working tree is clean. Create a branch (e.g. `tailwind-v4`).
412. **Inventory** every Tailwind entry point — there may be more than one: each CSS file with
42 `@tailwind`/`@import "tailwindcss"`, every `tailwind.config.*`, every `postcss.config.*`, the
43 bundler config (next/vite/webpack), and `package.json`. Monorepos: do this per package.
443. Record the current setup: `darkMode` value, custom `theme.extend`, `plugins`, the package
45 manager (npm/yarn/pnpm/bun), and two easy-to-miss config options that need special handling later:
46 **`prefix`** (v4 changes `tw-flex`→`tw:flex`) and **`theme.container`** (`center`/`padding` are gone
47 in v4 — recreate via `@utility container`).
484. **Capture a baseline of how the app looks now** so you can prove the migration changed nothing:
49 a screenshot set or a visual-regression run on v3 (see `references/05-verification-playwright.md`),
50 or at minimum a list of key pages to eyeball. Confirm the project builds green on v3 first.
5152### Step 1 — Run the official upgrade tool
5354```bash
55npx @tailwindcss/upgrade@latest # clean git tree required…
56npx @tailwindcss/upgrade@latest --force # …or pass --force if untracked/uncommitted files exist
57```
5859The tool refuses to run on a dirty tree (so you can review its diff). Commit/stash unrelated changes,
60or use `--force`. It updates dependencies, migrates the config to CSS where it can, rewrites
61`@tailwind` directives, and codemods most renamed/removed utilities in templates. **Review the full
62diff** — it is a starting point, not the finish line. If it errors (offline, exotic setup, unsupported
63config), fall back to the manual path in `references/01-breaking-changes.md` +
64`references/02-css-first-config.md` and continue. **Monorepos:** run the tool once per package root and
65confirm `tailwindcss` resolves to 4.x in *every* package's `node_modules` — a half-migrated workspace
66compiles some packages against v3.
6768### Step 2 — Reconcile dependencies & build plumbing
6970Verify the tool did these; finish any it missed (`references/04-framework-setups.md` for your stack):
7172- **Deps:** remove `tailwindcss@3`; add `tailwindcss@^4`. Remove `autoprefixer` and `postcss-import`
73 (v4 does prefixing + import inlining itself).
74- **PostCSS:** `postcss.config.*` → `{ plugins: { '@tailwindcss/postcss': {} } }` (add the
75 `@tailwindcss/postcss` dep). **Vite:** prefer `@tailwindcss/vite` over PostCSS. **CLI:** `npx
76 tailwindcss` → `npx @tailwindcss/cli`.
77- **CSS entry:** `@tailwind base/components/utilities;` → `@import "tailwindcss";`.
78- **Plugins:** delete now-built-in ones (`@tailwindcss/container-queries`, `@tailwindcss/aspect-ratio`,
79 line-clamp) — and remove their dead `theme`/usage. **`@tailwindcss/typography` stays** but is loaded
80 in CSS via `@plugin "@tailwindcss/typography";` and must be bumped to a v4-compatible release (≥0.5.16).
81- **`container` customization:** if v3 set `theme.container.center`/`padding`, those options are gone —
82 recreate as `@utility container { margin-inline: auto; padding-inline: 2rem; }` or every `container`
83 loses its centering/padding silently.
84- Reinstall with the project's package manager so the lockfile updates; the `tailwindcss` version must
85 resolve to 4.x.
8687### Step 3 — Changed-defaults audit + compat shims (the parity killers)
8889These changed defaults are the main thing that moves pixels (see Step 4 for the few non-default
90exceptions). Walk the checklist; for each "relied on", paste the shim into your main CSS (after
91`@import "tailwindcss";`). Full rationale in `references/03-compat-shims.md`.
9293- [ ] **Border/divide color** is now `currentColor` (was `gray-200`). If you use bare `border`/`divide`
94 without a color anywhere, add:
95 ```css
96 @layer base {
97 *, ::after, ::before, ::backdrop, ::file-selector-button {
98 border-color: var(--color-gray-200, currentColor);
99 }
100 }
101 ```
102- [ ] **Ring** is now 1px / `currentColor` (was 3px / `blue-500`). Replace bare `ring`→`ring-3`; if you
103 relied on the blue default add `ring-blue-500`. (Compat-only escape: `@theme { --default-ring-width:
104 3px; --default-ring-color: var(--color-blue-500); }`.)
105- [ ] **Placeholder** is now current text @ 50% (was `gray-400`). To keep v3 look:
106 ```css
107 @layer base { input::placeholder, textarea::placeholder { color: var(--color-gray-400); } }
108 ```
109- [ ] **Buttons** now use `cursor: default` (was `pointer`):
110 ```css
111 @layer base { button:not(:disabled), [role="button"]:not(:disabled) { cursor: pointer; } }
112 ```
113- [ ] **`<dialog>`** margins are reset (was centered): `@layer base { dialog { margin: auto; } }` if needed.
114- [ ] **Hover** now applies only on `(hover: hover)` devices. If your UI depends on tap-to-hover, add
115 `@custom-variant hover (&:hover);`.
116- [ ] **Dark mode:** if v3 used `darkMode: 'class'` (or a custom selector), add
117 `@custom-variant dark (&:is(.dark, .dark *));`. If it used `'media'`, v4's default already matches —
118 **do nothing** (adding the class variant would *break* media-driven dark mode).
119120> **Two of these are invisible to a screenshot harness:** the **button-cursor** and **hover-on-tap**
121> shims change behavior, not painted pixels, so visual parity (Step 5) can't confirm them. Decide them
122> by reasoning about the markup (do real `<button>`s / touch interactions rely on the v3 default?), not
123> by the pixel diff. Same for `outline-none`→`outline-hidden` (the difference only shows in forced-colors mode).
124125### Step 4 — Residual sweep (catch what the codemod missed)
126127Grep, then fix each real hit against the tables in `references/01-breaking-changes.md` (which cover the
128mechanical rewrites: `*-opacity-*`→`/<n>`, `flex-shrink/grow`→`shrink/grow`, `bg-gradient-to`→
129`bg-linear-to`, arbitrary `bg-[--x]`→`bg-(--x)`, `!flex`→`flex!`, `theme()`→`var(--…)`, etc.):
130131```bash
132grep -rEn '@tailwind |bg-gradient-to-|flex-shrink-|flex-grow-|overflow-ellipsis|decoration-slice|decoration-clone|[a-z]+-opacity-[0-9]|outline-none' src
133grep -rEn '\b(shadow|rounded|blur|drop-shadow|backdrop-blur)(["'"'"'`[:space:]])' src # bare scales — review, don't blind-replace
134grep -rEn 'transition(-colors)?\b' src # if paired with a focus-state outline-* color → set outline-color unconditionally
135# only if v3 used a prefix (Step 0): grep -rEn '\bPFX-[a-z]' src # PFX-flex → PFX:flex
136```
137138Three judgment calls the tables don't make for you:
139140- **Order bare renames after explicit ones:** `shadow-sm`→`shadow-xs` *before* bare `shadow`→`shadow-sm`
141 (same for rounded/blur/drop-shadow/backdrop-blur); word-boundary the bare form so `rounded-md`/
142 `shadow-lg` are untouched. The grep is noisy — `blur`/`shadow` collide with `placeholder="blur"` and
143 prose; fix only real class lists.
144- **`space-x/y-*` & `divide-x/y-*`** selectors changed to `:not(:last-child)` (no shim). If a list/inline
145 layout shifts, move it to flex/grid + `gap`.
146- **Gradients** now *preserve* stops across variants — add `via-none` to reset a 3-stop in a state.
147148### Step 5 — Verify (build + browser parity)
1491501. `build`, `lint`, `typecheck`, and unit tests must pass.
1512. **Prove the visual no-op:** re-run the baseline from Step 0 and confirm zero unintended diffs. Pay
152 special attention to: borders, focus rings, placeholders, dark mode, and any `prose` (typography)
153 content. Any diff maps to a missed Step 3 shim or Step 4 rename — fix it, don't accept it.
1543. **Check the screenshot-invisible changes by hand:** button cursor, hover-on-touch, and forced-colors
155 outline behavior (see the Step 3 note) — confirm these in a real browser, since no pixel diff will.
156157## Decision points
158159- **Port JS config to CSS, or keep it?** Default: port `theme.extend` to a CSS `@theme {}` block
160 (nested objects → flat vars: `colors.brand.500`→`--color-brand-500`, `boxShadow.card`→`--shadow-card`,
161 `fontFamily.sans`→`--font-sans`; use `@theme inline` for `hsl(var(--x))` references). **Keep the JS
162 file via `@config "../tailwind.config.js";`** when it carries plugin theming that's hard to express in
163 CSS — the classic case is **`@tailwindcss/typography` `theme.extend.typography` customization**
164 (custom `prose-*` modifiers). `@config` is officially supported v4 usage. `corePlugins`, `safelist`,
165 `separator` are NOT supported in JS config under v4 (safelist → `@source inline(...)`). Note:
166 Tailwind's **default** theme tokens (e.g. `--color-gray-200`, `--color-gray-400`) stay available even
167 when you keep a JS config via `@config`, so the Step 3 compat shims that reference them still resolve.
168 See `references/02-css-first-config.md`.
169- **CSS directive order:** `@import "tailwindcss";` must come first; place `@config "…";` and any
170 `@theme { … }` block after it.
171- **Custom `@layer utilities`/`@layer components` classes** → convert to `@utility name { … }`.
172- **Animation libs:** `tailwindcss-animate` (v3) → `tw-animate-css` (`@import "tw-animate-css";`),
173 utility names unchanged.
174- **Scoped styles** (Vue/Svelte/Astro `<style>`, CSS modules) lose theme access → add
175 `@reference "../app.css";` or use raw CSS vars. **No Sass/Less/Stylus** with v4.
176177## Manual fallback (no codemod)
178179deps → `postcss.config` → `@import "tailwindcss";` → port theme to `@theme` (or `@config`) → Step 3
180shims → Step 4 sweep → Step 5 verify. Exhaustive tables: `references/01-breaking-changes.md`,
181`references/02-css-first-config.md`, `references/03-compat-shims.md`.
182183## References
184185- `references/00-official-upgrade-guide.md` — the **official** Tailwind v3→v4 upgrade guide, verbatim
186 (source of truth; everything below distills it). https://tailwindcss.com/docs/upgrade-guide
187- `references/01-breaking-changes.md` — complete renamed / removed / syntax-change tables.
188- `references/02-css-first-config.md` — JS theme → `@theme`; `@config` fallback; plugins; `@utility`.
189- `references/03-compat-shims.md` — every changed default + its copy-paste shim and when it's needed.
190- `references/04-framework-setups.md` — Next.js, Vite, CLI, PostCSS, Astro, Vue, Svelte, CSS modules.
191- `references/05-verification-playwright.md` — capture-baseline-then-assert visual-parity recipe.
192- `references/06-gotchas.md` — rename ordering, typography prose port, gradient `via-none`, hover-on-tap, monorepos.
Run npx skillmds@latest add a-tokyo/tailwind-v3-to-v4-migration in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Migrate a project from Tailwind CSS v3 to v4 safely and completely. Runs the official `@tailwindcss/upgrade` codemod, then drives the judgment it can't: reconciling dependencies and PostCSS/Vite/CLI plumbing, porting JS config to CSS-first `@theme` (or keeping it via `@config`), auditing the v4 changed-defaults that silently alter appearance (border/ring/placeholder/cursor/dialog/hover) and applying compat shims, sweeping for renamed/removed utilities, and proving the migration is a visual no-op. Framework-agnostic (Next.js, Vite, Tailwind CLI, plain PostCSS; Vue/Svelte/Astro/CSS-module caveats). USE FOR: upgrading Tailwind 3 to 4, "tailwind v4 migration", `@tailwind` directives error, `@tailwindcss/postcss` setup, tailwind.config.js to CSS @theme, shadow-sm/rounded/ring/outline-none renames, bg-gradient-to to bg-linear-to. Activate only when an existing Tailwind v3 install is being upgraded. DO NOT USE FOR: a fresh v4 setup with no v3 present, downgrading v4 to v3, or non-Tailwind CSS. It is listed under Web & Frontend on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Capability flags: makes network calls. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free. This skill is licensed under MIT.
a-tokyo (@a-tokyo) published this skill. Their other Agent Skills are listed on their SkillMD profile.