The shadcn/ui registry is a distribution system for code. Instead of shipping a package, it ships source files—components, hooks, pages, configs—so you fully own and customize what lands in your repo. You can run your own registry, install from community registries, or even drop in items from a URL or local file.
Why use a registry (vs. a typical UI package)?
Own the code: clone-level control without forking a library.
Add only what you use: smaller bundles, fewer transitive deps.
Framework-agnostic distribution for registries (official UI targets React, but registries can ship any file types).
Quickstart (60 seconds)
# 1) Initialize shadcn in your project
npx shadcn@latest init
# 2) Add components by name, URL, or local file
npx shadcn@latest add button
npx shadcn@latest add https://example.com/r/hello-world.json
npx shadcn@latest add ./registry/items/hello-world.json
The CLI supports name, URL, or local path as arguments when adding resources.
Namespaced registries (v3+)
Shadcn 3.0 introduced namespaced registries so you can install from community or private registries using @namespace/item
. Configure them in components.json
and install with the CLI:
components.json
(basic)
{
"registries": {
"@acme": "https://registry.acme.com/resources/{name}.json"
}
}
npx shadcn@latest add @acme/button
Private registries can inject headers and params (useful for API keys):
{
"registries": {
"@private": {
"url": "https://api.company.com/registry/{name}.json",
"headers": { "Authorization": "Bearer ${REGISTRY_TOKEN}" },
"params": { "version": "latest" }
}
}
}
Real-world example: shadcnblocks via namespace
Shadcnblocks supports namespaced installs from their private registry (Pro plan) and documents a command like:
npx shadcn@beta add @shadcnblocks/hero125
They combine namespaced registry + API key auth for direct CLI installs. Check their changelog for the feature and how to get the exact command from their UI.
Tip: In your article, embed one or two copy buttons next to example commands for UX.
If you want a general “public-style” example (no auth), keep the generic @acme
snippet above using the official namespaced config.
How a registry is structured
registry.json (entry point)
Defines your registry’s name, homepage, and list of items. The CLI can build this for you.
{
"$schema": "https://ui.shadcn.com/schema/registry.json",
"name": "acme",
"homepage": "https://acme.com",
"items": [
{ "name": "hello-world", "type": "registry:block", "title": "Hello World",
"files": [{ "path": "registry/hello-world/hello-world.tsx", "type": "registry:component" }]
}
]
}
registry-item.json (each resource)
Items declare their files, dependencies, optional CSS vars, and can target paths (for routes/config).
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "hello-world",
"type": "registry:block",
"title": "Hello World",
"description": "A simple hello world component.",
"registryDependencies": ["button"],
"dependencies": ["lucide-react"],
"files": [
{ "path": "registry/hello-world/hello-world.tsx", "type": "registry:component" }
]
}
(Types like registry:block
, registry:component
, registry:file
, registry:page
are supported; see the spec.)
Build and host your own registry
Use the official registry template and the build
command. Items are served as static JSON under /public/r/[name].json
.
# Generate the registry JSON files
npx shadcn@latest build
The
build
step reads yourregistry.json
and emits item JSON—perfect for static hosting/CDN.
Installing from URL or local file
Sometimes you don’t want a namespace—just install a single item JSON hosted on GitHub or your CDN (or a local JSON during development). The CLI supports both flows.
Example: stitching shadcnblocks with your own registry
Keep your product-specific patterns in your registry (namespace
@acme
)Pull marketing blocks (e.g., hero, features, pricing) from shadcnblocks (
@shadcnblocks/hero125
, etc.)Your
components.json
holds both registries; the CLI installs code into your project.
Best practices
Start lean: add only what you ship; document variants as you go.
Lock versions: pin your private registry to a tag or digest in URLs/params.
Automate updates: script
npx shadcn@latest add @acme/*
for a weekly refresh in a throwaway branch, then review diffs.Secure private registries: use header-based auth +
${ENV_VARS}
incomponents.json
.
FAQ
Where does the CLI put files?
By default it reads components.json to determine targets; pages/files can also set a target path inside the item JSON.
Is there a starter repo?
Yes—official and community templates exist for quickly bootstrapping a registry.
How do shadcnblocks installs work?
They expose a namespaced registry with optional auth; you’ll see a ready-to-copy npx shadcn add @shadcnblocks/... command on their site.
Can I use the registry without React?
Yes. A registry distributes files—components, hooks, pages, configs—independent of framework.

Yucel is a digital product creator and content writer with a knack for full-stack development. He loves blending technical know-how with engaging storytelling to build practical, user-friendly solutions. When he's not coding or writing, you'll likely find him exploring new tech trends or getting inspired by nature.