🎉 New: Tailkits UI library — 200+ premium sections, launch price $29 🎉
Try 30+ Free →

Shadcn Registry Guide

Learn how the shadcn registry works.

by Yucel F. Sahan
4 min read
Updated on

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 - UI Components

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 your registry.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

  1. Start lean: add only what you ship; document variants as you go.

  2. Lock versions: pin your private registry to a tag or digest in URLs/params.

  3. Automate updates: script npx shadcn@latest add @acme/* for a weekly refresh in a throwaway branch, then review diffs.

  4. Secure private registries: use header-based auth + ${ENV_VARS} in components.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 F. Sahan

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.