Tailwind v4 for utilities, shadcn/ui for components. Why this combo is the SaaS default in 2026 and how to wire it well.
In 2026 the "component library or utilities?" debate is over. The answer is Tailwind v4 for utilities + shadcn/ui for components. Not a trade-off: two pieces that fit together.
This guide explains why this combo became the default and how to wire it well into a Next.js SaaS.
Tailwind v4 (2025) brought strong changes:
tailwind.config.js except edge cases)@theme to declare your palette directly in CSSExample globals.css:
@import 'tailwindcss';
@theme {
--color-brand: #d62828;
--font-display: 'Inter', sans-serif;
--radius-card: 0.75rem;
}Anywhere:
<button className="bg-brand rounded-card text-white">Click</button>No config, no extra imports.
shadcn/ui is a weird and great system. It's not a library you install (npm install). It's components you copy into your repo.
bunx shadcn@latest add button
bunx shadcn@latest add dialogThe command creates src/shared/components/ui/button.tsx in your repo. From there, it's yours: you
modify it, extend it, delete it. No update breaks because there's no package to version.
Pros:
Con: if a component updates, you decide manually whether to merge the changes.
My typical flow in a new project:
bunx shadcn@latest initFor domain-specific components (a BlogPostCard, a ProjectKanbanColumn), I write them myself with Tailwind directly. For everything "platform" (buttons, inputs, modals), shadcn/ui.
If you need Button variations, don't create PrimaryButton, SecondaryButton, DangerButton by copying code. Extend:
import { Button } from '@/shared/components/ui/button';
export function DangerButton(props: React.ComponentProps<typeof Button>) {
return <Button variant="destructive" {...props} />;
}Or add a variant to button.tsx with cva. Single source of truth.
Tailwind v4 + shadcn/ui ship dark mode built in. With next-themes:
import { ThemeProvider } from 'next-themes';
<ThemeProvider attribute="class" defaultTheme="system">
{children}
</ThemeProvider>;And every shadcn component respects dark: automatically. No extra CSS.
1. Mixing shadcn with MUI / Chakra: if you have a half-Material-UI codebase, don't add shadcn on top. Pick one and migrate. Two systems duplicate everything.
2. Over-customizing button.tsx: if you write 800 lines of variants, "code my way" becomes
"code I'm afraid to touch". Keep it small.
3. Not using CSS variables for tokens: if your brand uses #D62828 hardcoded in 47 places,
rebrand day is misery. Define it in @theme.
4. Forgetting the Tailwind Prettier plugin: without it, long class strings become hell.
prettier-plugin-tailwindcss sorts classes automatically.
For 90% of indie SaaS, shadcn/ui covers the base.
Tailwind v4 + shadcn/ui is the combo with the best speed / control / maintenance ratio for SaaS in 2026. Setup in an afternoon, code under your control, coherent design system.
If your boilerplate still rolls Bootstrap or MUI, look at shadcn. The DX gap from day 1 is real.
Subscribe for more tutorials and tips on building products with AI
On Apr 25 2026 MinIO archived its community edition. We migrated Click2Eat and yamltools.dev to self-hosted Garage (S3-compatible, AGPLv3). Four undocumented gotchas, the shared S3 API + product-dedicated CDN pattern, and a complete migration checklist.