v4 has exactly three build paths — pick one
Every v4 project compiles @import "tailwindcss" into a static,
tree-shaken CSS file through one of three entry points.
They all use the same engine (Lightning CSS, internally) and produce
the same output — the only difference is how the compiler is wired
into your build pipeline. There is no more tailwind.config.js
at the root by default; configuration lives in CSS via @theme,
@source, @utility, @plugin.
| path | package | wire it into | best for |
|---|---|---|---|
| CLI | @tailwindcss/cli |
a shell command / npm script | static sites, no-bundler setups, CI; also ships a standalone binary (no Node) |
| Vite plugin | @tailwindcss/vite |
vite.config.ts → plugins: [tailwindcss()] |
Vite apps (SvelteKit, Laravel, React Router, Nuxt, SolidJS) — fastest HMR |
| PostCSS plugin | @tailwindcss/postcss |
postcss.config.mjs → "@tailwindcss/postcss": {} |
frameworks already running PostCSS (Next.js, Angular, Rails, Symfony) |
| Play CDN (this page) | @tailwindcss/browser |
a single <script> tag |
prototyping / demos — compiles in the browser, not for production |
All four feed the same CSS entry point. The first three ship a static
dist.css; the Play CDN compiles at runtime from the live DOM.
the entry point — ONE line, then optional directives
In v4 the stylesheet is the configuration. There is no JS config
file to point at — the compiler reads your CSS top-to-bottom and treats
every at-rule (@theme, @source, @utility,
@custom-variant, @plugin) as an instruction.
A real-world entry file looks like this:
Migrating a v3 codebase? @config "../tailwind.config.js" bridges
a legacy JS config into v4 — but it's an escape hatch, not the destination.
1 · choose a build path → see the recommended setup
Click a path. The snippet below swaps to the exact install + config you
need. Every path ends with the same app.css from the panel
above — the difference is purely how the compiler is hooked in.
2 · Lightning CSS — the engine inside all three
v4 replaced PostCSS + autoprefixer + cssnano with Lightning CSS (a Rust-based CSS transformer). It runs inside the CLI, the Vite plugin, and the PostCSS plugin — you don't configure it directly, but it is why v4 builds are faster and the output is smaller. It handles four jobs the old stack split across three tools:
| job | v3 (old stack) | v4 (Lightning CSS) |
|---|---|---|
| minification | cssnano |
built-in — smarter shorthand merging, ~20-40% smaller on real apps |
| vendor prefixes | autoprefixer |
built-in — adds only the prefixes your browserslist needs |
| nesting polyfill | postcss-nesting |
built-in — compiles @nest / native nesting for older targets |
@import inlining |
postcss-import |
built-in — @import "tailwindcss" is resolved & inlined |
Representative minified+gzipped output sizes (a typical marketing page,
~200 utility classes). Your mileage depends on how many utilities you
actually use — v4 only ships what @source detected.
| build | raw CSS | minified | gzipped | vs v3 |
|---|---|---|---|---|
| v3 (postcss + cssnano + autoprefixer) | ~48 KB | ~14 KB | ~4.1 KB | baseline |
v4 (Lightning CSS, --minify) | ~46 KB | ~10 KB | ~3.2 KB | ~22% smaller gz |
3 · proof: this page's utilities compiled (the CDN works)
The card below is styled purely with Tailwind utility classes
(no inline styles for layout). The gold-check badge in the header asserts
getComputedStyle().display === "flex" on it once the CDN
finishes compiling. This is the same compilation step the CLI / Vite /
PostCSS plugin do at build time — here it happens in the browser
via the Play CDN. If the badge turns green, the pipeline works.
display: flex
Compiled from flex items-center gap-4.
utility layer OK
Preflight + theme + utilities all resolved.
display: — · gap: — · border-radius: —
intent → command
| intent | command / config | why |
|---|---|---|
| quick one-off build | npx @tailwindcss/cli -i app.css -o dist.css |
no install, scans cwd, writes one file |
| watch mode (dev) | npx @tailwindcss/cli -i app.css -o dist.css --watch |
rebuilds on source change; pair with your dev server |
| production build | npx @tailwindcss/cli -i app.css -o dist.css --minify |
Lightning CSS minify + dead-code removal |
| Vite app | npm i tailwindcss @tailwindcss/vite + plugin in config |
fastest HMR; zero-config once @import "tailwindcss" is in CSS |
| Next.js / Angular | npm i tailwindcss @tailwindcss/postcss + postcss.config |
plugs into the framework's existing PostCSS pipeline |
| target older browsers | set browserslist in package.json |
Lightning CSS polyfills nesting + adds prefixes accordingly |
| no Node available | download the standalone CLI binary from GitHub releases | single executable — same flags as the npm CLI |
| bridge a v3 config | @config "../tailwind.config.js"; in app.css |
escape hatch while migrating; not for greenfield |