React

What shadcn/ui is (and what it is not)

shadcn/ui copies React components into your repository through a CLI: readable files on Radix and Tailwind, with no npm package to update.

Key points

  • shadcn/ui distributes source files into the repository, not an npm package.
  • Behaviour comes from Radix UI and styling from Tailwind CSS: two MIT dependencies.
  • The installed code is yours, so updates are reconciled by hand.

shadcn/ui is a set of React components that a CLI copies into your repository, not a library you install as a dependency. Each component arrives as readable code built on Radix UI and Tailwind CSS.

What it actually writes into the repository

The init command creates components.json, adds the Radix and Tailwind dependencies and copies the tokens into app/globals.css. The add command writes one file per component into components/ui. After installation the code is yours: rename props, change a variant, delete a component.

What it is not

It is not an npm package: there is no version to bump in package.json. It is not a design system: it holds no product rules, content or governance. It is not a Figma kit. It is a distribution layer for code, and the MIT licence of shadcn/ui is documented at ui.shadcn.com.

How to install it

npx shadcn@latest init
npx shadcn@latest add button

Init asks for a style, a base colour and the file paths. The add command accepts a name from the public registry, a URL or a namespace: npx shadcn@latest add @eneui/hero. The record format is described in what a registry is.

A concrete example: a new variant

import { cva } from "class-variance-authority";

export const buttonVariants = cva(
  "inline-flex items-center justify-center rounded-md text-sm font-medium",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground",
        outline: "border border-input bg-background",
        quiet: "bg-transparent text-muted-foreground hover:bg-accent",
      },
    },
    defaultVariants: { variant: "default" },
  },
);

The quiet variant is one line in a file you own: no patch, no fork, no !important. The price is that the file stops receiving automatic updates, so the variant has to be compared by hand when the upstream component changes. In exchange the markup uses tokens such as bg-accent and text-muted-foreground, and dark mode keeps working without exceptions.

Where the boundary with Radix sits

shadcn/ui does not implement behaviour: it delegates to Radix UI, an MIT package that handles focus, keyboard and state. The comparison of the primitives is in Radix, Base UI and React Aria.

The count on 1 November 2026 over data/blocks.json, a snapshot taken on 31 October 2026, finds 381 blocks out of 1,556 with “shadcn” in the source identifier, spread over 5 sources; the shadcn-ui-ui source alone publishes 97. The figure measures how far the distribution model spread, not the quality of the copied code. The five identifiers are not all direct forks: some only publish blocks on top of shadcn/ui and never touch the component files.

A live record

In the EneUI catalogue the shadcn/ui sidebar record shows files, dependencies and the upstream licence; the same library appears with chart. To browse by category start from 111,985 components.

The limitation

No automatic updates. When shadcn/ui changes a component, your file stays as it was: run the command again, read the diff and reconcile by hand. With several repositories the drift grows in silence.

The decision rule

Install a component when you expect to change at least one prop or one token within the first month. If you will not touch it, an npm package with a stable API costs less maintenance. If you have to rewrite more than a third of the styling, start from Radix and write your own CSS: at that point you already pay for a fork, so own the code from the start.

The mistake to avoid

Adding arbitrary classes inside components/ui, for example bg-[#111], breaks palette changes and dark mode: the value bypasses every token. The override belongs at the call site, through className, or becomes a variant in the file. Repeat it three times and it is no longer an exception: it is a missing variant.

Where to continue

The step-by-step install is in how to install shadcn/ui; the copy-paste model against the headless package is in copy-paste or headless. For complete sections start from 1,556 blocks.

Frequently asked questions

Is shadcn/ui a component library?

No. It is a set of source files that a CLI copies into your repository. There is no shadcn/ui dependency in package.json to update.

Do I have to use Tailwind CSS with shadcn/ui?

Yes, if you use the distributed components. The styles are Tailwind classes and the tokens are CSS variables; rewriting the components on another styling engine is possible, but the work becomes yours.

Is shadcn/ui free?

Yes. The code ships under the MIT licence and you can use it in commercial products. Radix UI and Tailwind CSS are MIT as well.

Can I use it with Vue or Svelte?

Not the original package, which is React. Ports such as shadcn-vue and shadcn-svelte exist, with different APIs and maturity that you have to check record by record.

Why not use Radix UI directly?

Radix gives you unstyled headless primitives; shadcn/ui adds styling, tokens and pre-composed files. If you want total control of the CSS, Radix alone is the shorter road.