- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Attachment
- Avatar
- Badge
- Breadcrumb
- Bubble
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Collapsible
- Combobox
- Command
- Context Menu
- Data Table
- Date Picker
- Dialog
- Drawer
- Dropdown Menu
- Empty
- Field
- Form
- Hover Card
- Input
- Input Group
- Input OTP
- Item
- Kbd
- Label
- Marker
- Menubar
- Message
- Message Scroller
- Native Select
- Navigation Menu
- Number Field
- Pagination
- Pin Input
- Popover
- Progress
- Questionnaire
- Radio Group
- Range Calendar
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Spinner
- Stepper
- Switch
- Table
- Tabs
- Tags Input
- Textarea
- Toast
- Toggle
- Toggle Group
- Tooltip
- Typography
This guide will walk you through the process of setting up your own component registry.
It assumes you already have a project with components and would like to turn it into a registry.
registry.json
The registry.json file is only required if you're using the shadcn-vue CLI to build your registry.
If you're using a different build system, you can skip this step as long as your build system produces valid JSON files that conform to the registry-item schema specification.
Add a registry.json file
Create a registry.json file in the root of your project. Your project can be a Nuxt, Vite, or any other project that supports Vue.
{
"$schema": "https://shadcn-vue.com/schema/registry.json",
"name": "acme",
"homepage": "https://acme.com",
"items": [
// ...
]
}This registry.json file must conform to the registry schema specification.
Add a registry item
Create your component
Add your first component. Here's an example of a simple <HelloWorld /> component:
<script setup lang="ts">
import { Button } from "@/components/ui/button"
</script>
<template>
<Button>Hello World</Button>
</template>Note: This example places the component in the registry/new-york
directory. You can place it anywhere in your project as long as you set the
correct path in the registry.json file and you follow the registry/[NAME]
directory structure.
registry
└── new-york
└── HelloWorld
└── HelloWorld.vueImportant: If you're placing your component in a custom directory, make
sure it is configured in your tailwind.config.ts file.
// tailwind.config.ts
export default {
content: ["./registry/**/*.{js,ts,jsx,tsx,vue}"],
}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://shadcn-vue.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/HelloWorld/HelloWorld.vue",
"type": "registry:component"
}
]
}
]
}You define your registry item by adding a name, type, title, description and files.
For every file you add, you must specify the path and type of the file. The path is the relative path to the file from the root of your project. The type is the type of the file.
You can read more about the registry item schema and file types in the registry item schema docs.
Build your registry
Install the shadcn-vue CLI
Note: the build command is currently only available in the shadcn-vue@canary version of the CLI.
pnpm add shadcn-vue@latest
Add a build script
Add a registry:build script to your package.json file.
{
"scripts": {
"registry:build": "shadcn-vue build"
}
}Run the build script
Run the build script to generate the registry JSON files.
pnpm registry:build
Note: By default, the build script will generate the registry JSON files in public/r e.g public/r/hello-world.json.
You can change the output directory by passing the --output option. See the shadcn-vue build command for more information.
Serve your registry
If you're running your registry on Nuxt, you can now serve your registry by running the nuxt server. The command might differ for other frameworks.
pnpm dev
Your files will now be served at http://localhost:3000/r/[NAME].json eg. http://localhost:3000/r/hello-world.json.
Publish your registry
To make your registry available to other developers, you can publish it by deploying your project to a public URL.
Adding Auth
The shadcn-vue CLI does not offer a built-in way to add auth to your registry. We recommend handling authorization on your registry server.
A common simple approach is to use a token query parameter to authenticate requests to your registry. e.g. http://localhost:3000/r/hello-world.json?token=[SECURE_TOKEN_HERE].
Use the secure token to authenticate requests and return a 401 Unauthorized response if the token is invalid. Both the shadcn CLI and Open in v0 will handle the 401 response and display a message to the user.
Guidelines
Here are some guidelines to follow when building components for a registry.
- Place your registry item in the
registry/[STYLE]/[NAME]directory. I'm usingnew-yorkas an example. It can be anything you want as long as it's nested under theregistrydirectory. - The following properties are required for the block definition:
name,description,typeandfiles. - Make sure to list all registry dependencies in
registryDependencies. A registry dependency is the name of the component in the registry eg.input,button,card, etc or a URL to a registry item eg.http://localhost:3000/r/editor.json. - Make sure to list all dependencies in
dependencies. A dependency is the name of the package in the registry eg.zod,sonner, etc. To set a version, you can use thename@versionformat eg.zod@^3.20.0. - Imports should always use the
@/registrypath. eg.import { HelloWorld } from "@/registry/new-york/hello-world/hello-world" - Ideally, place your files within a registry item in
components,hooks,libdirectories.
Install using the CLI
To install a registry item using the shadcn-vue CLI, use the add command followed by the URL of the registry item.
pnpm dlx shadcn-vue@latest add http://localhost:3000/r/hello-world.json
Install from GitHub
If your registry lives in a public GitHub repository with a registry.json
at its root, you do not have to build, host or configure anything. The CLI can
read it directly:
pnpm dlx shadcn-vue@latest add owner/repo/hello-world
The CLI resolves the repository's default branch, reads registry.json from the
root, finds the item by name, and fetches each of its files[].path from the
same commit. Every file of an item comes from one commit, so a branch that moves
mid-install cannot give you a half-updated component.
Pinning a branch, tag or commit
Append #ref to install from somewhere other than the default branch:
pnpm dlx shadcn-vue@latest add owner/repo/hello-world#main pnpm dlx shadcn-vue@latest add owner/repo/hello-world#v1.2.0 pnpm dlx shadcn-vue@latest add owner/repo/hello-world#1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b
Branches win over tags when a name is ambiguous, and an annotated tag resolves to the commit it points at.
Listing what a repository publishes
pnpm dlx shadcn-vue@latest search owner/repo
Only install from repositories you trust
Adding a registry item runs third-party code on your machine. This is true of every registry — hosted, local or GitHub — but the GitHub form is worth calling out because it needs no configuration, so a single command from a README is enough to install from a repository you have never looked at.
A registry item can list npm dependencies, which the CLI installs with your
package manager, which in turn runs that package's install scripts. It can also
write files into your project. Treat npx shadcn-vue@latest add owner/repo/item
with the same care as npm install owner-repo — read the registry first if you
do not know who owns it.
The CLI does reject path and target values that are absolute or use .. to
escape the project, both for the item you asked for and at the point files are
written. That is a guard against mistakes and a hostile item's easiest trick; it
is not a sandbox.
Notes
- Item names may contain slashes.
owner/repo/forms/logininstalls the item namedforms/loginfrom the rootregistry.json. It is not a path to a nestedregistry.json. - The repository must be public.
raw.githubusercontent.comdoes not serve private repositories. Use a hosted registry with auth instead. - Git is required. The CLI shells out to
git ls-remoteto resolve the ref, which is what lets it find the default branch instead of guessingmain. registryDependenciesare resolved the usual way. A full URL is fetched as-is; a bare name such asbuttonresolves against the defaultshadcn-vueregistry, exactly as it does for any other registry item. Note that a dependency can point anywhere, so trusting a repository means trusting what it depends on too.
If you would rather not type the repository on every command, register a
namespace in components.json and install by that instead. A namespace maps to
a hosted registry URL template — not to a GitHub repository — so this is an
alternative to the GitHub form above rather than a shorthand for it:
{
"registries": {
"@acme": "https://acme.com/r/{name}.json"
}
}pnpm dlx shadcn-vue@latest add @acme/hello-world
On This Page
registry.jsonAdd a registry.json fileAdd a registry itemCreate your componentAdd your component to the registryBuild your registryInstall the shadcn-vue CLIAdd a build scriptRun the build scriptServe your registryPublish your registryAdding AuthGuidelinesInstall using the CLIInstall from GitHubPinning a branch, tag or commitListing what a repository publishesOnly install from repositories you trustNotes