shadcn/ui 2.3.0 brings first-class Tailwind v4 support. What changed, how to set it up in Next.js 16, and the gotchas to avoid.
For most of 2025, mixing shadcn/ui with Tailwind v4 meant living on the edge: canary flags, manual tweaks, and CSS that broke on the next update. With shadcn/ui 2.3.0, that era is over. Tailwind v4 is now first-class.
Here's what actually changed, how to set it up in a Next.js 16 project, and the gotchas that still bite.
tailwind.config.js in favor of CSS-based configuration. shadcn 2.3.0 generates components that expect this: your tokens live in @theme inside your CSS, not a JS config object.@import "tailwindcss" replaces the old three @tailwind directives.bunx shadcn@latest) detects v4 and scaffolds accordingly.@tailwindcss/postcss).globals.css with @import "tailwindcss"; and your @theme inline { ... } block mapping CSS variables to Tailwind tokens.bunx shadcn@latest init — pick the v4 path when prompted.bunx shadcn@latest add button card dialog.The key mental shift: in v4 there's no JS config to extend. A new color or font is a CSS variable plus an @theme inline entry, and Tailwind picks it up.
1. @theme vs @theme inline. If your tokens reference other CSS variables (the shadcn pattern: --primary → --color-primary), you need @theme inline. Plain @theme inlines the value at build time and your dark-mode overrides stop working. This is the single most common "why is my dark mode broken" bug.
2. OKLCH everywhere or nowhere. Don't mix HSL leftovers with OKLCH defaults — the two color spaces interpolate differently and your hovers will look off. Convert the whole palette.
3. The typography / prose plugin. @tailwindcss/typography needed config updates for v4. If your blog content looks unstyled, that's usually it.
4. Third-party components. Libraries still shipping v3 class assumptions can clash. Check anything that injects its own Tailwind classes.
Starting fresh: yes, no question. v4 + shadcn 2.3.0 is the default for a new Next.js 16 project, and CSS-first config is genuinely nicer once it clicks.
Got a v3 codebase that works: the migration is real but bounded — mostly the config move and the color-space conversion. Budget half a day for a medium app, and do it in its own PR, not bundled with features.
shadcn/ui 2.3.0 turns Tailwind v4 from "possible with effort" into "the recommended path." The config-in-CSS model and OKLCH tokens are the future; the only real work is the migration, and it's a one-time cost.
CREA.MBA ships on exactly this stack — Next.js 16, Tailwind v4, shadcn/ui 2.3.0 with OKLCH tokens and @theme inline already wired, dark mode included. The setup gotchas above are already solved in the boilerplate, so you start from a styling system that works instead of debugging color spaces.
Subscribe for more tutorials and tips on building products with AI