Registry
Run your own code registry with shadcn/ui.
You can use the shadcn CLI to run your own code registry. Running your own registry allows you to distribute your custom components, hooks, pages, config, rules and other files to any project.
The registry works with any project type and any framework, and is not limited to React.
Getting Started
Requirements
You are free to design and host your custom registry as you see fit. The only requirement is that your registry items must be valid JSON files that conform to the registry-item schema specification.
registry.json
The registry.json is the entry point for the registry. It contains the registry's name, homepage, and defines all the items present in the registry.
{
"$schema": "https://ui.shadcn.com/schema/registry.json",
"name": "acme",
"homepage": "https://acme.com",
"items": [
// ...
]
}
Add a registry item
Create your component
Add your first component:
import { Button } from "@/components/ui/button"
export function HelloWorld() {
return <Button>Hello World</Button>
}
Add your component to the registry
To add your component to the registry, you need to add your component definition to registry.json.
{
"$schema": "https://ui.shadcn.com/schema/registry.json",
"name": "acme",
"homepage": "https://acme.com",
"items": [
{
"name": "hello-world",
"type": "registry:block",
"title": "Hello World",
"description": "A simple hello world component.",
"files": [
{
"path": "registry/new-york/hello-world/hello-world.tsx",
"type": "registry:component"
}
]
}
]
}
Build your registry
npm install shadcn@latest
Add a registry:build script to your package.json file:
{
"scripts": {
"registry:build": "shadcn build"
}
}
Run the build script:
npm run registry:build
Serve your registry
npm run dev
Your files will be served at http://localhost:3000/r/[NAME].json eg. http://localhost:3000/r/hello-world.json.
Content Negotiation
The shadcn CLI supports HTTP Content Negotiation. This allows you to host your registry at any endpoint and serve different content depending on who is asking.
From a single URL, you can serve:
- HTML to browsers
- JSON to the
shadcnCLI - Markdown to AI agents and LLMs
Request headers
When the CLI makes a request to a registry, it sends:
- User-Agent:
shadcn - Accept:
application/vnd.shadcn.v1+json, application/json;q=0.9
Root hosting
In Next.js, express this as a rewrite in next.config.ts:
import type { NextConfig } from "next"
const nextConfig: NextConfig = {
async rewrites() {
return {
beforeFiles: [
{
source: "/",
has: [
{
type: "header",
key: "accept",
value: "(.*)application/vnd\\.shadcn\\.v1\\+json(.*)",
},
],
destination: "/r/index.json",
},
{
source: "/",
has: [
{
type: "header",
key: "user-agent",
value: "shadcn",
},
],
destination: "/r/index.json",
},
],
}
},
async headers() {
return [
{
source: "/",
headers: [{ key: "Vary", value: "Accept, User-Agent" }],
},
]
},
}
export default nextConfig
Or in an Express.js server:
app.get("/", (req, res) => {
res.vary("Accept")
res.vary("User-Agent")
if (req.accepts("application/vnd.shadcn.v1+json")) {
return res.json(registryData)
}
if (req.get("User-Agent") === "shadcn") {
return res.json(registryData)
}
res.send(htmlContent)
})
Namespaces
Registry namespaces let you configure multiple resource sources in one project. Resources can be any type of content: components, libraries, utilities, hooks, AI prompts, configuration files, themes, and more.
Examples
@shadcn/button- UI component from the shadcn registry@v0/dashboard- Dashboard component from the v0 registry@acme/auth-utils- Authentication utilities from your company's private registry
Basic Configuration
{
"registries": {
"@v0": "https://v0.dev/chat/b/{name}",
"@acme": "https://registry.acme.com/resources/{name}.json"
}
}
Advanced Configuration
{
"registries": {
"@private": {
"url": "https://api.company.com/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}"
}
}
}
}
URL Pattern System
Registry URLs support placeholders:
{name}- Replaced with the resource name{style}- Replaced with the current style configuration
Authentication
REGISTRY_TOKEN=your_secret_token_here
CLI Commands
# Install from a specific registry
npx shadcn@latest add @v0/dashboard
# Install multiple resources
npx shadcn@latest add @acme/button @lib/utils
# View a resource
npx shadcn@latest view @acme/button
# Search
npx shadcn@latest search @acme --query "auth"
Dependency Resolution
Resources can have dependencies across different registries:
{
"name": "dashboard",
"type": "registry:block",
"registryDependencies": [
"@shadcn/card",
"@v0/chart",
"@acme/data-table"
]
}
Creating Your Own Registry
- Implement the registry item schema
- Support the URL pattern with
{name}placeholder - Define resource types
- Handle authentication if needed
registry.json Schema
{
"$schema": "https://ui.shadcn.com/schema/registry.json",
"name": "shadcn",
"homepage": "https://ui.shadcn.com",
"items": [
{
"name": "hello-world",
"type": "registry:block",
"title": "Hello World",
"description": "A simple hello world component.",
"registryDependencies": [
"button",
"@acme/input-form"
],
"dependencies": ["is-even@3.0.0", "motion"],
"files": [
{
"path": "registry/new-york/hello-world/hello-world.tsx",
"type": "registry:component"
}
]
}
]
}
Properties
- $schema - The schema for the registry.json file
- name - The name of your registry
- homepage - The homepage of your registry
- items - The items in your registry
Guidelines
- Place your registry item in the
registry/[STYLE]/[NAME]directory - Required properties:
name,description,typeandfiles - List all registry dependencies in
registryDependencies - List all package dependencies in
dependencies - Imports should always use the
@/registrypath - Place files within a registry item in
components,hooks,libdirectories