shadcn/ui is a React component system that ships through a CLI instead of an npm package. You run a short command, the component's TypeScript source lands in your repo, and from there it's yours to edit and ship like the rest of your code. The project launched in 2023 and has become one of the first things a lot of React teams reach for, including teams leaning on AI coding tools like v0.
This guide covers what shadcn/ui is, the stack it runs on, the features that make it work in production, and how it pairs with v0 and Vercel.
Copy link to headingWhat is shadcn/ui?
shadcn/ui is an open-source React component system that distributes source through a CLI you run from your project. The project describes itself as a code distribution platform for accessible, well-designed components, and that framing lines up with how it works. When you run the CLI, it writes a component file into your project, and from that point, the markup, Tailwind classes, and CVA variants belong to your repo (yes, every file).
The project shipped in January 2023 and quickly took off in the React community on GitHub, with shadcn (the engineer behind it) joining Vercel shortly after. Adoption has climbed alongside AI-assisted development, since coding agents and engineers can both read and edit the same component files.
Copy link to headingHow shadcn/ui is different from a traditional component library
Most React component libraries hide their implementation behind a package boundary. shadcn/ui puts the source in your repo instead, so your team owns the UI layer the same way you own the rest of the code.
Copy link to headingCopy-paste, not npm install
Material UI and Chakra UI install as packages, and the component code lives inside node_modules where you can't edit it without forking. shadcn/ui ships a CLI that writes the source straight into your repo, usually at components/ui/.
Behavioral dependencies like Base UI or Radix Primitives still install through npm, but the JSX, Tailwind classes, and CVA variants land in your repo as editable files. Your team reviews them in pull requests alongside the rest of the application code.
Copy link to headingSource code that lives in your repo
Every component file lives in your repo from the moment the CLI drops it, so when you want to change a button's padding, you crack open button.tsx and edit the file directly. Debugging an unexpected layout means reading your own source, since the component logic isn't hidden away in node_modules.
The catch is that you take on the maintenance work yourself, since npm update won't touch the copied files. Your team decides when to pull upstream changes back in.
No version lock-in or hidden abstractions
Standard component libraries tie your UI layer to a specific major version, and a v6 release can force migrations across every component that imports from the package. With shadcn/ui you don't run into that, since the source is already yours.
The CLI's --reinstall flag re-scaffolds components from upstream templates when you want fresh copies, but the components in your repo don't change just because an upstream maintainer cut a release.
Copy link to headingThe shadcn/ui tech stack
shadcn/ui is a thin Tailwind layer over a few well-known building blocks. Each piece handles a specific job, and together they make up every file you'll edit.
Four pieces show up in every component file:
UI Primitives: Base UI is the default component library in shadcn/ui, with Radix still supported via
-b radix. Both provide accessible headless behavior underneath copied React components.Tailwind CSS: Tailwind is a hard requirement, applied as utility classes inside the copied component files. To switch palettes or enable dark mode, you tweak CSS custom properties like --
primary, --background, --secondary, --destructive, and --radius.Class Variance Authority: CVA defines type-safe component variants. You declare base classes and variant combinations once with
cva(), and TypeScript types forvariant,size, and other props get generated automatically.clsx and tailwind-merge: The
cn()utility combinesclsxfor conditional class construction withtailwind-mergefor Tailwind-specific conflict resolution. When you pass aclassNameprop to override a component's base styles,tailwind-mergeremoves the conflicting base classes from the output.
All four sit underneath React as the component runtime. The CLI's --template flag covers Next.js, Vite, TanStack Start, React Router, Laravel, and Astro with React, and you'll find community ports for Vue, Svelte, and Flutter.
Copy link to headingKey features of shadcn/ui
Once a project gets past the first few components, the tools around shadcn/ui start doing real work. The CLI, the Blocks gallery, the theming system, and the registry format are what let your team run a folder of TypeScript across multiple repos without it turning into a mess.
Copy link to headingThe shadcn CLI
The CLI handles almost everything you do day to day with shadcn/ui. You run shadcn init to write a components.json config and pull in base dependencies, shadcn add button card dialog to drop component source files into your project, and shadcn add --diff to see what's changed upstream since you last copied a file. Every command operates on real files in your repo, so the output shows up as a normal pull request diff.
Copy link to headingBlocks and pre-built layouts
Blocks are pre-composed layouts assembled from the same primitives the catalog ships. Authentication forms, dashboards, sidebar navigation, and pricing pages all copy in as full sections, which shortens the gap between an empty route and a working interface. Each block copies the needed files into your app, often across app/ and components/, so blocks are edited and reviewed through the normal component workflow.
Copy link to headingThemes and the theme editor
Theming runs through CSS custom properties defined in globals.css. Tokens like --primary, --secondary, --destructive, and --radius carry the visual identity, and a hosted theme editor lets you preview palette and radius changes against the full component catalog before anything lands in the repo.
Copy link to headingCustom component registries
The registry system lets your team publish its own components, hooks, pages, and config files in the same shape the public registry uses. Your platform group can host a private registry, point the CLI at it, and let product engineers pull approved components with the same npx shadcn add workflow they already know.
Copy link to headingshadcn/ui vs. other component libraries
Across these libraries, the comparison usually comes down to where the component source lives. Every other React UI project is distributed through npm, and shadcn/ui hands the files to your repo.
Copy link to headingvs. Material UI, Chakra UI, and Ant Design
Material UI ships the @mui/material package with a wide catalog and a polished implementation of Material Design. Chakra UI customizes through an sx prop and a theme object, and Ant Design covers data grids and complex form widgets out of the box. In all three cases, you update through npm update and customize through the library's APIs.
shadcn/ui covers common UI surfaces with composable primitives, and the catalog doesn't include packaged data widgets like advanced grids or rich form systems. The ownership model gives you full source control and a neutral visual language. The cost is a smaller catalog than Material UI ships out of the box, with no packaged design system to start from. Our shadcn/ui vs. Material UI breakdown covers the trade-offs in more detail.
Copy link to headingvs. Radix UI and Headless UI
Radix Primitives is the behavior layer underneath every interactive shadcn/ui component. If you use Radix on its own, you'll write every line of styling yourself, since Primitives ship unstyled by design. shadcn/ui adds Tailwind classes and CVA variants on top of those same primitives, so most of that work is already done for you. Our shadcn/ui vs. Radix UI guide covers the relationship in more detail.
Headless UI from the Tailwind team covers a smaller set of accessible, unstyled components for projects already on Tailwind. It works when you want a handful of interactive primitives without the full component system shadcn/ui ships.
Copy link to headingWhen shadcn/ui is the right choice
shadcn/ui makes the most sense when you're already on Tailwind, you want long-term ownership of the component layer, and editing source files directly fits your workflow. The clearest cases look like this:
Tailwind-first stacks: You're already using Tailwind for styling, so utility classes inside the component files stay consistent with the rest of your codebase. The same mental model carries from page to component without a context switch.
Custom design systems: Your design team needs to reshape markup, variants, or behavior past the defaults. Editable source files give you that control without forking a third-party package.
AI-assisted workflows: Coding agents and tools like v0 read and write component source directly, so the generated code drops right into the files you'd edit by hand.
Greenfield React or Next.js projects: You don't have an existing component layer to migrate, so the copy-paste model lands cleanly from day one.
The model fits less well if you need advanced data grids, complex form widgets, or upstream updates handled through a package manager. In those cases, a packaged library is usually the faster path.
Copy link to headingShip shadcn/ui apps faster with v0 and Vercel
v0, Vercel's AI app builder, uses shadcn/ui as part of its default stack when it generates React code. The model reads the same component files you'd edit by hand, so the generated output drops into your Next.js repo without translation.
That pairing carries through the rest of the deployment cycle. The generated components ship through git like any other React code, and the runtime pieces your app needs sit alongside shadcn/ui without separate plumbing. A few patterns hold up across teams running this stack:
One pipeline from prompt to production: v0 output lands in your Next.js repo, ships to a preview deployment on every pull request, and rolls out through the same git-based release flow.
Fluid compute for server logic: Your API routes, server actions, and AI calls run on Fluid compute, which only charges while a function is actively running.
AI SDK on the application layer: The AI SDK handles model calls and streaming on the backend while shadcn/ui handles the UI surface, with both layers reading from the same TypeScript codebase.
Your UI changes, server logic, and AI calls all go through the same review and deploy cycle.
Copy link to headingChoosing shadcn/ui for your next React project
shadcn/ui has caught on with React teams because engineers want to edit component source directly, and AI coding tools work best when the files are already in your repo.
The harder call is whether the trade-off makes sense for your team. Owning the source means your repo takes on the maintenance work that an npm package would absorb. You also get no version lock-in and no packaged design language to fight against, since the components are regular files in your codebase. For a project already running Tailwind, the trade-off usually works out. Standardizing on Material UI or Chakra UI puts you in a different spot, and sticking with what you have is usually the better call.
You can start on Vercel with npx shadcn@latest init, generate components from a v0 prompt, and ship a preview URL the same day. From there, the same code goes to production whenever you're ready to push it.
Copy link to headingFrequently asked questions about shadcn/ui
Copy link to headingIs shadcn/ui free to use?
Yes. shadcn/ui ships under the MIT license, so you can use it in personal and commercial projects as long as you keep the copyright notice in source copies. No attribution shows up in the rendered UI, and no usage caps apply once the components are in your repo. Your shadcn/ui app deploys on Vercel the same way as any other Next.js or React app.
Copy link to headingDoes shadcn/ui work outside of React?
No. The official project targets React frameworks: Next.js, Vite, TanStack Start, React Router, Astro with React integration, and Laravel. You'll find community ports for Vue, Svelte, and Flutter, but those aren't maintained by the core team. If you want a starting point, the SaaS starter template ships with Next.js and shadcn/ui already wired in.
Copy link to headingIs shadcn/ui production-ready?
Yes. Interactive components inherit accessibility from Base UI and Radix Primitives, which follow WAI-ARIA authoring practices and are tested with major screen readers. Production apps run shadcn/ui today, and most teams ship changes through preview deployments on Vercel before they hit the main branch.
Copy link to headingWho created shadcn/ui?
shadcn/ui was built by an engineer who goes by shadcn (the GitHub handle). The project started as a personal side project in January 2023, gained traction through Twitter and the React community, and now runs as a Vercel-supported open-source project. The CLI, registry, and v0 integration all build on that core open-code model.