Runs locally · nothing uploaded

Tailwind v3 to v4 Migration Tool

Keep v3
tailwind.config.js / .ts · v3
app.css · v47 theme values
Migration notesnothing to do by hand
  • notecontent — v4 finds your template files automatically, so these globs usually aren't needed: ./src/**/*.{html,js,jsx}. Add @source "…" only for files it would miss (e.g. a UI package in node_modules); the path is relative to the CSS file, not to the old config.

About this tool

Paste a Tailwind v3 config and get the v4 CSS file, with every theme value moved into @theme, plugins and dark mode converted to their v4 directives, and a list of anything that needs doing by hand. The Class names tab updates renamed utilities in your markup. Everything runs in your browser.

?

Why use this instead of migrating by hand?

⇢
Check before you commit
See exactly what your config becomes in v4 before touching the repo: every @theme variable, plugin and variant, plus a list of what needs a human.
⌁
No Node 20 or project needed
The official upgrade tool needs Node 20+ and a git repo. This works on any machine, for one config or one component, in the browser.
✓
Output that compiles
Every mapping follows Tailwind's own upgrade guide and theme reference, and the conversions are tested by compiling the result with Tailwind v4.
🔒
Your config stays private
The config is parsed, never executed, and nothing is uploaded or put in the URL. Safe for client and company code.
▶

How to use it

01
Paste your config
Drop in tailwind.config.js or .ts: module.exports, export default and satisfies Config all work.
02
Read the notes
Anything v4 can't express (corePlugins, theme functions, inline plugins) is listed as a "by hand" step instead of being dropped silently.
03
Keep v3 defaults if you need them
Tick the defaults v4 changed (border colour, ring width, button cursor…) to add Tailwind's official snippets to the output.
04
Migrate your classes
Switch to Class names and paste markup: renamed utilities like shadow → shadow-sm and bg-opacity-50 → /50 are fixed in one pass.
⇄

Renamed and removed classes in v4

Tailwind v3Tailwind v4
shadow-smshadow-xs
shadowshadow-sm
rounded-smrounded-xs
roundedrounded-sm
blur-smblur-xs
blurblur-sm
ringring-3
outline-noneoutline-hidden
flex-growgrow
flex-shrink-0shrink-0
overflow-ellipsistext-ellipsis
bg-black bg-opacity-50bg-black/50
!flexflex!
bg-[--brand]bg-(--brand)

From Tailwind's official upgrade guide. The radius change applies to every side too: rounded-t becomes rounded-t-sm.

◇

A config, before and after

v3 config
// tailwind.config.js (v3)
module.exports = {
  darkMode: 'class',
  theme: {
    extend: {
      colors: { brand: { 500: '#8b5cf6' } },
      screens: { '3xl': '1920px' },
    },
  },
  plugins: [require('@tailwindcss/typography')],
}
v4 CSS
/* app.css (v4) */
@import "tailwindcss";
@plugin "@tailwindcss/typography";

@theme {
  --color-brand-500: #8b5cf6;
  --breakpoint-3xl: 1920px;
}

@custom-variant dark (&:where(.dark, .dark *));
✦

Things worth knowing

01
Renames happen in one pass
Find-and-replace turns shadow into shadow-sm and then into shadow-xs. Each class here is renamed once, so that double shift can't happen.
02
shadcn/ui tokens use @theme inline
Values that point at other variables, like hsl(var(--primary)), go in an @theme inline block so utilities use the value directly.
03
Content globs are usually unnecessary
v4 finds your template files automatically. Add @source only for files it would miss, such as a UI package inside node_modules.
04
max-w-prose is fixed in v4
It is always 65ch and ignores theme overrides. If you customised it, use an arbitrary value or a new container name.
?

Frequently asked questions

01

How does tailwind.config.js map to Tailwind v4?

In v4 the theme lives in CSS. Each theme key becomes a variable namespace inside @theme: colors become --color-*, fontFamily --font-*, fontSize --text-* with --text-*--line-height, screens --breakpoint-*, borderRadius --radius-*, boxShadow --shadow-*, and keyframes move inside @theme next to --animate-*. Plugins become @plugin, darkMode class becomes @custom-variant dark, and the three @tailwind lines become @import "tailwindcss". Keys that replaced a whole scale (theme instead of theme.extend) start with a reset such as --color-*: initial.

02

Is this the same as the official npx @tailwindcss/upgrade tool?

It covers the same config mappings and class renames, but works differently. The official tool runs in your project, needs Node 20 or newer and a clean git branch, and rewrites every file at once, which is the right choice for a whole repository. This page is for checking a config before you commit, migrating on a machine without Node 20, or converting one component. You can use both: preview here, then run the official tool.

03

Which Tailwind classes were renamed in v4?

The small end of several scales moved down a step: shadow-sm is now shadow-xs and shadow is now shadow-sm, and the same applies to rounded, blur, drop-shadow and backdrop-blur. outline-none became outline-hidden, ring became ring-3 because the default ring is now 1px, flex-grow and flex-shrink became grow and shrink, and the opacity utilities such as bg-opacity-50 were removed in favour of the slash syntax bg-black/50. The Class names tab applies all of these in one pass, so shadow never turns into shadow-xs by being renamed twice.

04

Does it work with shadcn/ui configs?

Yes. shadcn/ui colours such as hsl(var(--primary)) and radii such as calc(var(--radius) - 2px) point at your own CSS variables, so they are written into an @theme inline block. That makes utilities like bg-primary use the value directly instead of a nested variable. The accordion keyframes and animations move into @theme, and tailwindcss-animate becomes an @plugin line.

05

Why does my site look different after upgrading to v4?

Usually because v4 changed some defaults rather than class names. Borders now default to the current text colour instead of gray-200, the default ring is 1px and currentColor instead of 3px blue, placeholders use the text colour at half opacity, buttons use the default cursor instead of a pointer, and dialog margins are reset. Each of these has an official snippet that restores the v3 behaviour; tick them under Keep v3 defaults to add them to your CSS. Spacing utilities like space-y-4 also use a different selector now, which can change lists that wrap.

06

Is my config uploaded anywhere?

No. The conversion runs entirely in your browser and the config is parsed as text, never executed, so nothing in it can run. Nothing is sent to a server or stored in the page address, which makes it safe for private client and company configs.

Related tools

Search CodeFronts

Loading…