Registry
Scaffold and author installable registry items under registry/items.
Registry items live under registry/items/** and can be installed by shadcn-compatible CLIs. Start new items with the scaffold command so the folder, _registry.mdx, source file, metadata, and generated registry JSON paths follow the template conventions.
bun --bun ./scripts/new.ts --type registry:ui --name example-card --description "A compact card component."Or, run the command without flags if you want an interactive prompt (recommended).
bun --bun ./scripts/new.tsItem Types
Choose the registry type from what the item installs:
| Type | Use For | Folder |
|---|---|---|
registry:ui | Shadcn-style UI components | registry/items/components/** |
registry:component | Components outside components/ui | registry/items/components/** |
registry:block | Larger composed UI patterns | registry/items/blocks/** |
registry:hook | React hooks | registry/items/hooks/** |
registry:lib | Utility or helper modules | registry/items/lib/** |
registry:page | App page files with explicit targets | registry/items/pages/** |
registry:file | Other files with explicit install targets | registry/items/files/** |
registry:style | Style-level CSS and dependency metadata | registry/items/styles/** |
registry:theme | Theme CSS variables | registry/items/themes/** |
registry:font | Font metadata | registry/items/fonts/** |
registry:base | Design system base configuration | registry/items/bases/** |
registry:item | Universal or metadata-only items | registry/items/items/** |
The scaffold creates each item in its own folder:
registry/items/components/example-card/
_registry.mdx
_preview.tsx
example-card.tsxCLI Flags
Use flags for agent-friendly and CI-friendly scaffolding:
bun --bun ./scripts/new.ts --type registry:block --name stats-panel --description "A metrics panel with reusable sample data."
bun --bun ./scripts/new.ts --type registry:ui --name prompt-input --description "An AI prompt input." --target @ui/ai/prompt-input.tsx
bun --bun ./scripts/new.ts --type registry:page --name dashboard-page --description "A starter dashboard page." --target app/dashboard/page.tsx
bun --bun ./scripts/new.ts --type registry:file --name chart-theme --description "Shared chart theme tokens." --target styles/chart-theme.css --file-extension css
bun --bun ./scripts/new.ts --type registry:font --name font-inter --description "Inter font metadata." --font-family "'Inter Variable', sans-serif" --font-import Inter --font-variable=--font-sansSupported flags:
--type: registry item type. Defaults toregistry:ui.--name: required kebab-case item name.--title: optional public title. Defaults from the name.--description: required public description.--target: required forregistry:pageandregistry:file; optional for source-backed items that need a custom install path, including shadcn target placeholders like@ui/ai/prompt-input.tsx.--file-extension: forregistry:fileand targetedregistry:item; defaults tots.--font-family,--font-import,--font-variable: required for noninteractiveregistry:fontscaffolds.
Use bun --bun ./scripts/new.ts --help to print the full usage.
Authoring
Use _registry.mdx for public metadata and usage docs. Put the optional named Preview export in _preview.tsx. Keep both files private to authoring; never list them in files.
For one-file registry:ui items, the catalog infers <item-name>.tsx. Hooks, libs, blocks, pages, target paths, and multi-file items should list files explicitly. Metadata-only styles, themes, fonts, bases, and universal items can omit files.
List authored source files with paths relative to the item _registry.mdx file. The catalog automatically emits files[].target placeholders such as @ui/<name>.tsx, @components/<name>.tsx, @hooks/<name>.ts, and @lib/<name>.ts for file types that should install through the user's components.json aliases. Use explicit target values for registry:page, registry:file, and nested alias installs like @ui/ai/prompt-input.tsx; do not add registry/items/** prefixes or a separate sourcePath field.
Use localRegistryDependencies for dependencies on other local registry items.
Component Variants
If a component uses cva from class-variance-authority, keep that definition in a colocated <name>.variants.ts file. Do not call cva in the component .tsx. Use .ts, not .tsx.
Treat button as the reference:
registry/items/components/button/
_registry.mdx
_preview.tsx
button.tsx
button.types.ts
button.variants.tsbutton.tsx imports the CVA helper and renders. button.variants.ts owns every cva() call for that item. If one folder has several CVA helpers, keep them in the same .variants.ts file. Put VariantProps in a colocated <name>.types.ts file when the item has named variant types, as Button does.
Each variants file should follow this shape:
import { cva } from "class-variance-authority";
import { cn } from "cn";
const exampleBase = cn("inline-flex items-center rounded-md");
const exampleConfig = {
variants: {
variant: {
primary: "bg-primary text-primary-foreground",
outline: "border border-border bg-background",
},
size: {
sm: "h-8 px-3",
md: "h-9 px-4",
},
},
compoundVariants: [],
defaultVariants: {
variant: "primary",
size: "md",
},
} as const;
export const exampleCva = cva(exampleBase, {
...exampleConfig,
compoundVariants: [...exampleConfig.compoundVariants],
});
export const EXAMPLE_VARIANTS = Object.keys(
exampleConfig.variants.variant,
) as (keyof typeof exampleConfig.variants.variant)[];
export const EXAMPLE_SIZES = Object.keys(
exampleConfig.variants.size,
) as (keyof typeof exampleConfig.variants.size)[];
export const exampleVariants = exampleCva;Always include compoundVariants on the config, even when it is empty, and spread it into cva() so the as const config stays compatible. Export a key array for each variant axis that stories or other items need to iterate. Re-export the CVA helper from the component file only when another item already consumes that public name.
List the variants file in _registry.mdx files, and add class-variance-authority to dependencies. Include .types.ts when the item has one:
dependencies:
- class-variance-authority
files:
- path: example.tsx
type: registry:ui
target: components/ui/example/example.tsx
- path: example.types.ts
type: registry:ui
target: components/ui/example/example.types.ts
- path: example.variants.ts
type: registry:ui
target: components/ui/example/example.variants.tsAfter editing an item, run vp check --fix on touched files and bun --bun ./scripts/doctor.ts. Run vp build when registry docs, routes, JSON output, catalog loading, or source loading changed.