Web development

How to use the shadcn/ui CLI, command by command

After init the CLI has five more useful commands: view, search, add --diff, build for your own registry and migrate for theme tokens.

Key points

  • `view` and `search` read a registry without writing files into the project.
  • `add --dry-run` lists files, `add --diff` shows lines: only the second one sees a conflict.
  • `build` turns your `registry.json` into JSON that installs with `add`.

After installation the shadcn/ui CLI covers four jobs: view reads the source, add --diff shows the lines that change and build turns your registry.json into a registry. The version measured is shadcn 4.23.0.

See a component before installing it

npx shadcn@latest search @shadcn -q "data table"
npx shadcn@latest view button card dialog

search queries a registry and prints names and descriptions; view prints the file contents. Neither writes to the project: use them when you cannot remember what a block does.

The diff before the write

npx shadcn@latest add card --dry-run
npx shadcn@latest add card --diff components/ui/card.tsx

--dry-run lists the files the command would write; --diff shows the lines that would change in a file you already edited. When the component has been yours for months, the diff is the only check that sees the conflict before the overwrite.

Configuration as data

npx shadcn@latest info --json
npx shadcn@latest info --json > shadcn-info.json

info prints aliases, the CSS path, the base colour and the style. With --json the output goes into a script: in CI you can check that the CSS path did not change after a merge.

Publish a registry of your own

npx shadcn@latest build
npx shadcn@latest build registry.json --output ./public/r

build reads registry.json and writes the JSON files to public/r: from there your components install with add and a URL. The licence stays yours, because a registry is a distribution format, not a fork.

Migrations and presets

npx shadcn@latest migrate --list
npx shadcn@latest migrate cn
npx shadcn@latest preset decode a2r6bw

migrate --list lists the available migrations: cn replaces clsx and tailwind-merge, base-color changes the theme tokens. preset decode explains what a preset code contains before you apply it.

A named limitation

The CLI does not walk up the tree: it looks for components.json in the current folder or the one passed with -c. In a monorepo, a command run from the root fails even when the file sits two levels down.

Where to continue

The EneUI catalogue starts from the shadcn library, with 61 components, and from records such as the sidebar; the 1,556 block previews show the assembled result. The first step is still installing shadcn/ui, the second is adding a block. To pick a theme read free versus premium themes; for private registries, tokens and namespaces.

Frequently asked questions

What does the view command do?

It prints a component's code without installing it. Use it to check dependencies and style before writing files into the project, and to compare two registries.

What is the difference between --dry-run and --diff?

dry-run lists the files that would be written, diff shows the lines that would change in one specific file. The first is a list, the second a comparison.

Can I install from a private registry?

Yes, add accepts a URL in place of the component name. When the registry needs authentication, the token goes in the registries entry of components.json, not on the command line.

Why does build not find registry.json?

Because the command reads ./registry.json relative to the current folder. Pass the path as an argument, or move the file into the root you run the command from.

Does the CLI work without components.json?

For view, search and migrate cn, yes. For add and info, no, because without components.json it cannot know the aliases, the CSS path or the base component.