registry-item.json
Core Idea
Full field-by-field schema for a single registry item — the unit installed by shadcn add. JSON Schema: https://ui.shadcn.com/schema/registry-item.json. This is the schema to master for building MyAlienUI/ComponentsAlienUI-style registries.
Key Concepts
type: Determines default install location and semantics; see Reference Tables for the full enum.
registryDependencies: Item addresses — bare name (button, resolves to built-in shadcn item, NEVER same-repo), @namespace/item, owner/repo/item (optionally #ref for branch/tag/SHA — refs are NOT inherited by transitive deps), full URL, or local file path (./editor.json).
files[].path / .type / .target: path is the source location used at build time; type sets the file's registry type; target is required only for registry:page and registry:file, and can use ~ for project root or alias placeholders (@components/, @ui/, @lib/, @hooks/ — NOT @utils/, since utils points to a file not a directory). target wins over type for install location when both are set.
tailwind: DEPRECATED — use cssVars.theme instead for Tailwind v4 projects.
cssVars: { theme, light, dark } — CSS custom properties injected into the project's theme and per-mode color/token overrides.
css: Raw CSS rule injection — @layer base/components, @utility (incl. -* functional utilities), @keyframes, @plugin (must pair with a dependencies entry for the npm package).
envVars: Adds to .env.local/.env without overwriting; dev/example values only.
font: Required for registry:font; only provider: "google" supported today.
docs: Custom message shown by the CLI on install (e.g. setup instructions for an API key).
categories: Free-form organizational tags.
meta: Arbitrary key/value metadata for external tooling.
Code Examples
{
"$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", "@acme/input-form", "https://example.com/r/foo"],
"dependencies": ["is-even@3.0.0", "motion"],
"devDependencies": ["tw-animate-css"],
"files": [
{ "path": "registry/new-york/hello-world/hello-world.tsx", "type": "registry:component" },
{ "path": "registry/new-york/hello-world/use-hello-world.ts", "type": "registry:hook" }
],
"cssVars": {
"theme": { "font-heading": "Poppins, sans-serif" },
"light": { "brand": "oklch(0.205 0.015 18)" },
"dark": { "brand": "oklch(0.205 0.015 18)" }
}
}
- O que demonstra: item completo e representativo, combinando dependências npm com versão, registry deps de três formatos, múltiplos arquivos tipados e cssVars por tema/modo.
{
"files": [
{ "path": "registry/new-york/example/format-date.ts", "type": "registry:ui", "target": "@lib/format-date.ts" }
]
}
- O que demonstra:
target decide onde o arquivo é escrito mesmo divergindo do type declarado.
Reference Tables
type values
| Type | Use for |
|---|
registry:base | entire design systems |
registry:block | complex components, multiple files |
registry:component | simple components |
registry:font | fonts |
registry:lib | libs and utils |
registry:hook | hooks |
registry:ui | UI components / single-file primitives |
registry:page | page or file-based routes (target required) |
registry:file | misc files (target required) |
registry:style | registry styles (e.g. new-york) |
registry:theme | themes |
registry:item | universal registry items |
Top-level fields
| Field | Type | Notes |
|---|
$schema | string | schema URL |
name | string | unique within registry |
title | string | short human-readable title |
description | string | longer explanation |
type | string | see enum above |
author | string | e.g. "John Doe <john@doe.com>" |
dependencies | string[] | npm packages, name@version for pinning |
devDependencies | string[] | npm dev-only packages |
registryDependencies | string[] | item addresses (bare / @ns/item / owner/repo/item#ref / URL / local path) |
files | File[] | see below |
tailwind | object | DEPRECATED, use cssVars.theme |
cssVars | {theme,light,dark} | CSS custom properties |
css | object | raw CSS injection (@layer, @utility, @keyframes, @plugin, @import) |
envVars | Record<string,string> | dev/example env vars only |
font | object | required for registry:font |
docs | string | custom install-time message |
categories | string[] | organizational tags |
meta | object | arbitrary metadata |
files[] entry
| Field | Required | Notes |
|---|
path | yes | source path used at build time |
type | yes | one of the type enum values |
target | conditional | required for registry:page/registry:file; supports ~/ and alias placeholders |
target placeholders
| Placeholder | Resolves to |
|---|
@components/ | aliases.components |
@ui/ | aliases.ui |
@lib/ | aliases.lib |
@hooks/ | aliases.hooks |
(@utils/) | not supported — utils is a file, not a directory |
font object
| Property | Type | Required | Description |
|---|
family | string | yes | CSS font-family value |
provider | string | yes | only google supported |
import | string | yes | import name from next/font/google |
variable | string | yes | CSS var name (e.g. --font-sans) |
weight | string[] | no | font weights to include |
subsets | string[] | no | font subsets |
selector | string | no | CSS selector target; defaults to html |
dependency | string | no | npm package for non-Next.js projects |
Anti-patterns
- Bare
registryDependencies name expecting repo-local resolution: "button" always means the built-in shadcn item; use owner/repo/button for same-repo items.
- Setting
tailwind config instead of cssVars.theme: deprecated path, Tailwind v4 projects should use cssVars.theme.
- Omitting
target on registry:page/registry:file: these two types require it; without it the CLI can't place the file.
- Using
@utils/ as a target placeholder: unsupported since utils resolves to a single file, not a directory — embedded/unknown placeholders like @foo/bar.ts are written literally as foo/bar.ts, not resolved.
- Assuming a GitHub
#ref propagates to transitive registry dependencies: refs are NOT inherited; pin every dependency that needs reproducibility individually.
Key Takeaways
type is the single most consequential field — it drives both default install location and how the CLI/MCP interprets the item's purpose.
target (when present) always overrides type's default placement, and supports both literal paths (~/foo.config.js) and alias placeholders (@ui/, @lib/, etc.) that adapt to the consumer's own components.json aliases.
- For a private multi-project registry (like MyAlienUI/ComponentsAlienUI), lean on
registryDependencies with mixed address styles (bare/namespace/URL) plus cssVars for design tokens — this is the full building-block vocabulary the CLI understands.
css field ordering when combining directives: @import → @plugin → other rules (@layer, @utility, @keyframes).
- Universal, framework-agnostic items are possible with
type: "registry:item" as long as every file declares an explicit target.
Connects To
- registry-examples (ch100): worked examples for every
type value in this schema.
- registry-json (ch107): parent schema —
items[] entries must satisfy this spec.
- registry-namespace (ch104):
registryDependencies namespace-address resolution rules.
- registry-faq (ch101): common follow-ups on
cssVars usage.