Back to Plate

Registry Authoring and Addresses

templates/plate-playground-template/.agents/skills/shadcn/registry.md

53.0.88.6 KB
Original Source

Registry Authoring and Addresses

Use this reference when the user wants to create, fix, publish, or reason about a shadcn registry.

Mental Model

A registry has two forms:

  • Source registry: an authored registry.json in a project or repository. It may use include and file paths that point at source files.
  • Built registry: generated JSON files served to CLI consumers, usually from public/r. Use npx shadcn@latest build to create this form.

The CLI installer consumes registry item payloads. A source registry is a way to author those payloads from real files.

Registry items are not limited to React components. They can distribute components, hooks, utilities, design tokens, pages, config files, docs, rules, workflows, templates, MCP files, and other project files.

Root registry.json

The root registry file should define registry metadata and either items or include.

json
{
  "$schema": "https://ui.shadcn.com/schema/registry.json",
  "name": "acme",
  "homepage": "https://acme.com",
  "items": [
    {
      "name": "absolute-url",
      "type": "registry:lib",
      "title": "Absolute URL",
      "description": "A utility to turn any path into an absolute URL.",
      "files": [
        {
          "path": "lib/absolute-url.ts",
          "type": "registry:lib"
        }
      ]
    }
  ]
}

Root registry rules:

  • Root registry.json must include name and homepage.
  • items is an array of registry item definitions.
  • include may be used to split the source registry into multiple files.
  • Included registry files may omit name and homepage.

Include

Use include to keep large registries modular.

json
{
  "$schema": "https://ui.shadcn.com/schema/registry.json",
  "name": "acme",
  "homepage": "https://acme.com",
  "include": ["registry/ui/registry.json", "registry/blocks/registry.json"]
}

Include rules:

  • Include paths are relative to the registry.json that declares them.
  • Include paths must explicitly point to a registry.json file.
  • Do not use remote URLs, absolute paths, or parent traversal (..).
  • Item file paths are relative to the registry file that declares the item.
  • Duplicate item names fail across the resolved registry.

Example included file:

json
{
  "items": [
    {
      "name": "button",
      "type": "registry:ui",
      "files": [
        {
          "path": "button.tsx",
          "type": "registry:ui"
        }
      ]
    }
  ]
}

If this file is at registry/ui/registry.json, then button.tsx is read from registry/ui/button.tsx, and the built item path is emitted relative to the root registry.

Item Definitions

Common item fields:

json
{
  "name": "login-form",
  "type": "registry:block",
  "title": "Login Form",
  "description": "A login form with email and password fields.",
  "dependencies": ["zod"],
  "registryDependencies": ["button", "input", "label"],
  "files": [
    {
      "path": "blocks/login-form.tsx",
      "type": "registry:block"
    }
  ],
  "cssVars": {
    "light": {
      "brand": "oklch(0.62 0.18 250)"
    },
    "dark": {
      "brand": "oklch(0.72 0.16 250)"
    }
  }
}

Important fields:

  • name: the installable item name. It is not necessarily a file path.
  • type: one of the registry item types, such as registry:ui, registry:block, registry:lib, registry:hook, registry:file, registry:page, registry:theme, registry:style, registry:font, or registry:item.
  • files: source files copied or generated by the item.
  • dependencies: npm runtime dependencies.
  • devDependencies: npm development dependencies.
  • registryDependencies: other registry items required by this item.
  • cssVars, css, tailwind, envVars, and docs: optional install-time additions.

File rules:

  • File paths are relative to the declaring registry.json.
  • registry:file and registry:page files require a target.
  • Do not use remote file URLs in source registry file paths.
  • Keep source files copy-pasteable: no hidden app-only imports.

Registry Dependencies

registryDependencies entries are item addresses, not file paths.

json
{
  "name": "login-form",
  "type": "registry:block",
  "registryDependencies": ["button", "@acme/input", "acme/ui/card#v1.2.0"],
  "files": [
    {
      "path": "blocks/login-form.tsx",
      "type": "registry:block"
    }
  ]
}

Dependency rules:

  • Bare names such as "button" mean official shadcn items.
  • Bare names never mean same-registry or same-repository items.
  • Namespaced dependencies use @namespace/item-name.
  • GitHub dependencies use owner/repo/item-name.
  • Pin GitHub dependencies with owner/repo/item-name#ref when needed.
  • Refs are not inherited. If owner/repo/foo#v2 depends on bar from the same repo at v2, write owner/repo/bar#v2.
  • Do not use relative dependencies such as "./bar".

Address Schemes

When reasoning about a registry item string, classify it first.

AddressSchemeMeaning
buttonshadcnOfficial shadcn item named button.
@acme/buttonnamespaceItem button from configured registry @acme.
@acme/ui/buttonnamespaceItem ui/button from configured registry @acme.
https://example.com/r/button.jsonurlBuilt registry item JSON at that URL.
./button.jsonfileBuilt registry item JSON on disk.
acme/ui/buttongithubItem button from GitHub repo acme/ui.
acme/ui/forms/login#maingithubItem forms/login from GitHub repo acme/ui at ref main.

For namespace and GitHub addresses, slashful item names are allowed and are item names, not file paths. Addresses ending in .json keep file-address precedence, so acme/ui/data/schema.json is treated as a file path, not a GitHub item address.

GitHub Registries

A public GitHub repository can act as a source registry when it has a root registry.json.

txt
owner/repo/item-name[#ref]

Rules:

  • The first two path segments are GitHub owner and repo.
  • All remaining path segments are the registry item name.
  • The source entrypoint is always root registry.json.
  • GitHub registries are source registries consumed directly by the CLI. They do not require shadcn build or generated item JSON files.
  • include follows the same source-registry rules as local registries.
  • Currently, GitHub addresses support public github.com repositories only.
  • Private repos and GitHub Enterprise require explicit product decisions.

When implementing GitHub registry fetching, resolve refs to a commit SHA before reading source files. Do not read moving refs directly from raw.githubusercontent.com, because branch-like refs can be cached for several minutes.

Preferred flow:

txt
owner/repo[#ref]
  -> resolve ref with git ls-remote
  -> commit SHA
  -> read https://raw.githubusercontent.com/{owner}/{repo}/{sha}/registry.json
  -> read includes and item files from the same SHA

This keeps a command on one consistent repository snapshot.

Full 40-character commit SHAs are already stable and can be used directly. Branches, tags, and short refs require Git so the CLI can resolve them to a commit SHA first.

Build and Verify

Use the CLI to build source registries:

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

Use CLI commands to inspect the result:

bash
npx shadcn@latest list @acme
npx shadcn@latest search @acme -q "login"
npx shadcn@latest view @acme/login-form
npx shadcn@latest add @acme/login-form --dry-run
npx shadcn@latest registry validate ./registry.json

Use GitHub addresses directly for public GitHub registries:

bash
npx shadcn@latest list owner/repo
npx shadcn@latest search owner/repo -q "login"
npx shadcn@latest view owner/repo/item
npx shadcn@latest add owner/repo/item --dry-run
npx shadcn@latest registry validate owner/repo

When working on registry implementation in the shadcn/ui codebase:

  • Keep address parsing pure and testable.
  • Do not add side effects to validators.
  • Preserve existing behavior for official shadcn, namespace, URL, and file schemes.
  • Add tests for address parsing, source loading, dependency resolution, list, search, view, and add paths.
  • Prefer small source-reader abstractions over a plugin system until there are multiple real providers.