shadcn/ui for AI Builders: The Default UI Stack in 2026
Why this matters
Open any output from v0, Bolt, or Lovable in 2026. Look at the imports. Buttons, cards, dialogs, dropdowns — all from @/components/ui. That's shadcn. Cursor's templates default to it. Claude Code, when asked for a component, will reach for it. shadcn/ui is the default UI stack of vibecoding, and it's not by accident.
The trick is shadcn isn't a component library you install. It's a CLI that copies source code into your repo. You own every line. Tailwind handles the styling. Radix handles the accessibility primitives underneath. AI tools love this because they can read, modify, and recombine your components without fighting an opaque dependency.
The setup
You need:
- A Next.js, Remix, Vite, or Astro project (basically anything with React + Tailwind support)
- Tailwind CSS already wired (the shadcn CLI will help if it isn't)
- Node 18+ (24 LTS recommended)
If you generated your project with v0, Bolt, or Lovable, all of this is already there.
Step 1: Install shadcn via the CLI
The CLI handles config, deps, and the components folder structure. One command:
npx shadcn@latest init
It will ask:
- Style (default or new-york — pick new-york for tighter visuals)
- Base color (slate is a safe default)
- Where to put components (
@/components/uiis canonical) - Whether to use CSS variables (yes — it makes theming trivial)
This creates components.json, globals.css with the design tokens, and a lib/utils.ts with the cn() helper. That's the whole framework. There is no shadcn package in your node_modules.
Step 2: Add components from the registry
When you need a button, you add it. The CLI fetches the source and drops it into your repo:
npx shadcn@latest add button card dialog dropdown-menu input
Now components/ui/button.tsx is a real file you can read and modify. When the AI builder generates a screen using <Button>, it knows exactly what props are available because it can see the source.
The registry has 50+ components, and there are community registries for specific niches (forms, charts, dashboards). Use the --registry flag to pull from custom registries:
npx shadcn@latest add https://example.com/r/calendar.json
When Cursor or Claude Code generates a screen, prompt it explicitly: "Use only shadcn primitives I have installed in @/components/ui — don't introduce new dependencies." That single line keeps the dependency footprint flat for months.
Step 3: Theme via CSS variables
shadcn's design tokens live in your globals.css as CSS variables. To rebrand the entire app, you change a few HSL values:
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--primary: 240 5.9% 10%;
--primary-foreground: 0 0% 98%;
--radius: 0.75rem;
}
.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 240 5.9% 10%;
}
}
For anything more ambitious — gradients, custom radius scales, brand-specific tokens — the shadcn theme generator ↗ gives you a ready-made block. Paste it in, you're done.
Step 4: Compose with v0, Bolt, and Lovable
The killer combo: design components in v0, copy the JSX, paste into your shadcn-wired project. Because v0 outputs the same primitives you've installed, the paste works on the first try. No "missing import" cleanup.
Lovable and Bolt go further — they assume shadcn from the start. When you prompt "add a settings page," you get one composed from primitives that already match the rest of your app.
If you're starting a new project, generate the visual shell with v0 → push to GitHub → clone → npx shadcn@latest init if not present → continue iterating in Cursor or Claude Code. Same primitives, three different surfaces.
Common mistakes
- Installing shadcn as a package — It's not on npm. It's a CLI that copies code. If you tried
npm i shadcn, that's a different (unrelated) package. - Editing the design tokens deep in component files — Always change tokens in
globals.css. Components reference variables; if you hardcode colors in the component, your dark mode breaks. - Adding all 50 components on day 1 — Add as you need them. Each one is real source you'll have to maintain. Bloat on demand only.
- Mixing two component libraries — shadcn + Material UI in the same app is tech debt. Pick one. AI tools handle this badly anyway.
- Forgetting
cn()— Thatcn()helper merges Tailwind classes correctly. Use it whenever you compose className props or you'll get specificity bugs.
What's next
With shadcn wired, you've got the visual layer the rest of the 2026 vibecoder stack expects — pair with Vercel for hosting and Supabase for the backend and you can ship a production-quality AI app from a weekend prompt.
What are you building?
Claim your handle and publish your app for the world to see.
Claim your handle →