Tailwind v4 Nextjs 16 Setup: Config, Fonts and 5 Fixes
You want Tailwind v4 in a Next.js 16 app and the guides disagree: one says postcss.config.mjs, a fresh create-next-app writes something else, and your old tailwind.config.js does nothing. This Tailwind v4 Nextjs guide sets it up from scratch, explains what each line does, wires next/font into the theme, and fixes the five errors that make Tailwind v4 look like it is not working.
What we checked on November 6, 2026: the templates inside create-next-app 16.4.5 (published November 3), the Next.js 16 docs that ship in node_modules/next/dist/docs, Tailwind's own Next.js guide, and the CSS that Tailwind 4.3.3 compiles for every snippet below. This site, wingo-ui.com, runs Next.js 16.3 with Tailwind 4.3.3 and the PostCSS plugin.
What does a Tailwind v4 setup in Next.js 16 need?
Four things, fewer than v3 needed. A Tailwind v4 Nextjs 16 setup is complete with:
- two dev dependencies:
tailwindcssand a bundler integration (@tailwindcss/postcssor@tailwindcss/turbopack), - one config entry that registers the integration,
@import "tailwindcss";at the top ofapp/globals.css,import "./globals.css"inapp/layout.tsx.
What is gone: tailwind.config.js, the content array, the three @tailwind directives, autoprefixer and postcss-import. Tailwind v4 finds your class names by scanning the project (it skips node_modules and anything in .gitignore), adds vendor prefixes itself, and reads the theme from CSS.
How do I install Tailwind v4 in Next.js?
Let create-next-app write the setup for a new app. An existing app takes four small edits with the PostCSS plugin.
New app: let create-next-app write it
--yes takes your saved preferences or the defaults, which include TypeScript, ESLint, the App Router, the @/* alias and Tailwind. Since version 16.4.0 (October 6, 2026) the Tailwind part changed. We read the 16.4.5 templates: when the bundler is Turbopack, the default, the CLI installs @tailwindcss/turbopack instead of @tailwindcss/postcss, skips postcss.config.mjs and writes a loader rule into next.config.ts:
That rule is Turbopack configuration, so a webpack build (next dev --webpack) never reads it. If you need webpack for a plugin, use the PostCSS route below instead. Version 16.3.6 and earlier still wrote postcss.config.mjs, which is why tutorials from this summer show a different file than your new app has.
Existing app: install Tailwind v4 with PostCSS
This is the route the Next.js CSS docs and Tailwind's Next.js guide both document, and it works under Turbopack and webpack.
Run npm run dev, put className="text-3xl font-bold" on a heading, and it should render bold and large. That is all an install of Tailwind v4 in Next.js 16 needs. Use one integration, not both: either postcss.config.mjs or the Turbopack loader rule.
Where does the Tailwind v4 config go in Next.js?
In app/globals.css, right after the import. The Tailwind v4 config is CSS: every variable in an @theme block becomes both a CSS variable and a set of utilities.
That gives you bg-brand, text-brand, rounded-card and a 3xl: breakpoint. The variable's namespace decides which utilities it feeds: --color-* for colors, --font-* for font families, --radius-*, --shadow-*, --breakpoint-* and so on.
Values that change between light and dark belong in plain CSS variables, mapped with @theme inline:
With inline, Tailwind writes the reference into the utility, so bg-surface compiles to background-color: var(--surface) and follows the nearest .dark. Without inline, the utility points at --color-surface, which resolves where it is declared, on :root. That still works while .dark sits on <html>, as next-themes puts it, but a .dark section deeper in the page keeps the light value. The pillar post on Tailwind v4 design tokens goes through a complete token set: surfaces, text levels, tones, elevation and a contrast check.
How do I use next/font with Tailwind v4?
next/font exposes each font as a CSS variable, and @theme inline turns that variable into font-sans or font-mono. The layout sets the variables on <html>:
Use inline here, as the Next.js font docs do. A plain @theme reference resolves on :root, which only works while the font classes sit on <html>. Move them to <body> and font-sans silently falls back to the system font; with inline it works on either element.
Tailwind's base styles set the html font to --font-sans, so the whole page picks up Geist with no class. There is one catch in the 16.4.5 starter: its globals.css ends with body { font-family: Arial, Helvetica, sans-serif; }. The demo page hides that by putting font-sans on its wrapper div. Replace page.tsx with your own markup and everything renders in Arial. Delete that line. Adding font-sans to <body> does not help, for the reason in error 3 below.
Why is Tailwind v4 not working in Next.js?
Usually one of five setup errors, each with a message or a symptom you can match.
1. "It looks like you're trying to use tailwindcss directly as a PostCSS plugin"
Your postcss.config.mjs still says tailwindcss: {}. In v4 the PostCSS plugin moved to its own package. Install @tailwindcss/postcss, replace the key, and remove autoprefixer while you are there.
2. tailwind.config.js changes do nothing
v4 does not look for a config file. Move theme.extend into @theme, darkMode into @custom-variant (error 4) and plugins into @plugin "plugin-name"; lines. For a gradual move you can load the old file with @config "../tailwind.config.js"; under the import. The same change explains why npx tailwindcss init fails: the tailwindcss package no longer ships a command line tool. Migrating a shadcn project? The shadcn Tailwind v4 migration guide covers the codemod and what it misses.
3. Some classes are missing or lose to other CSS
Open DevTools on the element. If the class has no rule at all, Tailwind never saw it:
- Files outside the project root. In a monorepo, components in
packages/uiare not scanned fromapps/web. Add@source "../../../packages/ui/src";toapps/web/app/globals.css(the path is relative to the CSS file). - Class names built at runtime.
`bg-${tone}-500`never appears as text, so it is never generated. Write the full names in a map,{ danger: "bg-red-500", success: "bg-green-500" }. @applyin a CSS module. A.module.cssfile is compiled on its own and fails with "Cannot apply unknown utility class". Put@reference "../globals.css";(the path from the module to your stylesheet) at the top of the module.
If the rule exists but is crossed out, cascade layers are the cause. v4 puts utilities in @layer utilities, and any rule outside a layer beats every layered rule, whatever its specificity. That is why the starter's unlayered body { font-family: Arial } wins over font-sans on the same element. Wrap your own global rules in @layer base { ... } and utilities win again.
4. dark: classes ignore the theme toggle
By default dark: compiles to @media (prefers-color-scheme: dark), so it follows the operating system and ignores the class that next-themes sets. Add one line:
Then pass attribute="class" to the next-themes ThemeProvider and delete the starter's @media (prefers-color-scheme: dark) block, or the system setting keeps overriding your toggle. The Tailwind v4 dark mode guide covers tokens and the toggle, and the next-themes hydration error post covers the flash on reload.
5. New classes appear only after a restart
You add a class, save, and nothing changes until you restart next dev. A Tailwind discussion from May 4, 2026 (opens in a new tab) reports exactly this on Next.js 16. Since Next.js 16.1, Turbopack also keeps its dev cache on disk in .next/dev/cache/turbopack and reuses it on restart, so a stale result can survive one. The order that works for us:
- Stop the dev server and delete the cache:
rm -rf .next. - Check that only one integration runs (no PostCSS config next to a Turbopack loader rule).
- To isolate the bundler, run
next dev --webpackwith the PostCSS setup. If the problem disappears, it is a Turbopack issue worth reporting with a reproduction.
How do I add components on top of this setup?
A component library built for Tailwind v4 only needs the tokens it uses to exist in your @theme. Wingo UI's init command merges them into app/globals.css and adds the cn helper:
The Button, Card and UIProvider are free items. They use the semantic tokens from the sections above (bg-surface, shadow-raised, text-muted-foreground), so they switch with your .dark class without a single dark: prefix. A server page can render them directly:
$ npx wingo-ui@latest add cardShared defaults go in the root layout, so every button in the app gets the same shape without repeating props. UIProvider is a client component; a server layout can render it and pass plain objects:
$ npx wingo-ui@latest add buttonThe Next.js component library setup guide walks through init, "use client" boundaries and updates in detail, and the theming docs list every token. More posts on this stack live under Next.js and Tailwind CSS.
What do the final files look like?
For an existing app on the PostCSS route, three files hold the entire setup:
The layout is the next/font version above. On the create-next-app route, swap postcss.config.mjs for the turbopack.rules entry in next.config.ts; globals.css and the layout stay the same.
Next step
If the setup works and you want components that already speak these tokens, npx wingo-ui@latest add button card installs both free components from this post, with UIProvider as a dependency, and needs no account. All 75 free items install the same way, and the installation docs cover Vite and existing projects.
FAQ
Does Tailwind v4 need a tailwind.config.js in Next.js?
No. Tailwind v4 reads its configuration from CSS: theme values go in @theme blocks in app/globals.css and source files are detected without a content array. A v3 config file is ignored unless you load it with @config "../tailwind.config.js"; in the stylesheet.
Should I use @tailwindcss/postcss or @tailwindcss/turbopack?
Both compile the same CSS under Turbopack, the default bundler in Next.js 16. create-next-app 16.4 and later writes the Turbopack loader; the Tailwind and Next.js docs still show the PostCSS plugin, which also works when you run next dev --webpack. Pick one, not both.
Why are my Tailwind classes not applied in Next.js?
Check four things in order: the class exists in the built CSS (DevTools), the file is inside the detected sources (add @source for monorepo packages), the class name is written out in full (no bg-${color}-500), and no unlayered rule in another stylesheet overrides it.
Do I still need autoprefixer with Tailwind v4?
No. Tailwind v4 adds vendor prefixes and handles @import itself, so the PostCSS config needs only @tailwindcss/postcss. Remove autoprefixer and postcss-import from older configs.
Which browsers does Tailwind v4 support?
Tailwind's compatibility page lists Chrome 111, Safari 16.4 and Firefox 128 as the minimum, because v4 relies on cascade layers, @property and color-mix(). If you must support older browsers, stay on Tailwind v3.4.
- Tailwind CSS v4
- Next.js 16
- Setup
- Turbopack
- next/font

