Registry Schema
Purpose and Scope
The registry schema is the contract between a registry author, the hosted JSON files, and the shadcn CLI that consumes them. A registry is a distribution system for code: it can publish components, hooks, utilities, pages, styles, themes, config, rules, and other files as JSON-addressable items. The schema matters because a registry is intentionally not tied to one application framework. The official registry documentation states that any framework can host a registry as long as it serves JSON over HTTP, while the CLI depends on predictable fields to resolve, validate, and install that content.
Sources: apps/v4/content/docs/registry/registry-item-json.mdx, packages/shadcn/src/registry/schema.ts
There are two related JSON shapes to keep separate. A registry catalog, commonly registry.json, is the entry point that names the registry, links to its homepage, and lists the items it provides. A registry item, commonly represented by registry-item.json or an item-specific JSON payload, describes one installable unit. The item schema is where authors declare the item name, type, title, description, package dependencies, registry dependencies, files, Tailwind additions, and CSS variables. That separation lets clients discover many items from an index but install each item using a precise item contract.
Sources: apps/v4/content/docs/registry/registry-item-json.mdx
Relevant Source Files
apps/v4/content/docs/registry/registry-item-json.mdx- Reader-facing specification for a registry item, including the exampleregistry-item.json, field definitions, supported public item types, and examples for dependencies, files, and CSS variables.apps/v4/content/docs/changelog/2025-02-registry-schema.mdx- Changelog note explaining why the February 2025 schema update exists: flat JSON distribution, custom styles, third-party registry composition, LLM-generated registry content, themes, CSS vars, hooks, animations, and Tailwind layers/utilities.packages/shadcn/src/registry/schema.ts- Runtime Zod schema definitions used by the CLI package for registry configuration, project configuration, registry item types, file records, Tailwind additions, CSS variable maps, and recursive CSS structures.packages/shadcn/src/schema/index.ts- Public schema entry point that re-exports the registry schema module, making these schema definitions available from the package schema surface.
Registry Item JSON Contract
A registry item begins with a $schema URL pointing at https://ui.shadcn.com/schema/registry-item.json. This field is optional from a parsing perspective in many JSON workflows, but it is important for editor tooling and for authors who want validation feedback while writing registry files. The documented example uses name, type, title, and description as the human and machine identifiers for the item. The name identifies the item inside a registry, while the title and description are intended for people browsing or reviewing the item.
Sources: apps/v4/content/docs/registry/registry-item-json.mdx
The type field is more than a label. The docs say it is used to determine the type and target path when an item is resolved for a project, and the source schema encodes the accepted type names as an enum. Public item types visible in both the documentation and implementation include registry:base, registry:block, registry:component, registry:font, registry:lib, registry:hook, registry:ui, registry:page, registry:file, registry:style, registry:theme, and registry:item. The implementation also includes registry:example and registry:internal as internal-use values, so registry authors should prefer the documented public values unless they are working on repository internals.
Sources: apps/v4/content/docs/registry/registry-item-json.mdx, packages/shadcn/src/registry/schema.ts
Registry items can express two kinds of dependency relationships. dependencies and devDependencies describe npm packages, including optional version suffixes such as an @version form shown in the docs. registryDependencies describe other registry items that should be installed alongside or before the current item. The example intentionally mixes local item names, namespaced registry addresses such as @acme/input-form, and full URLs such as https://example.com/r/foo. That flexibility is what lets a registry item compose local building blocks, third-party registry content, and externally hosted item JSON without hard-coding everything into one file.
Sources: apps/v4/content/docs/registry/registry-item-json.mdx
Validation Behavior and Source-Level Rules
The CLI schema implementation is written with Zod, which makes validation rules executable inside the package. Registry source configuration is represented by registryConfigSchema, a record whose keys must start with @. That matches the namespace convention used throughout the registry docs, for example @v0 or @acme. Each configured registry value can be either a string URL template or an advanced object. In both cases, the URL must include the {name} placeholder, because the CLI needs a deterministic way to substitute the requested item name into the registry endpoint.
Sources: packages/shadcn/src/registry/schema.ts
The advanced registry configuration object supports url, optional params, and optional headers. This is the source-level basis for authenticated or parameterized registry sources: headers can carry request metadata, and params can supply query values, while the {name} requirement preserves the same item-addressing model as the simple string form. The result is a compact contract that supports both public registries and protected registries without changing the shape of item JSON. It also explains why namespaced registry configuration belongs in project config rather than in each registry item.
Sources: packages/shadcn/src/registry/schema.ts
Project-level configuration is handled by rawConfigSchema and extended by configSchema. The raw schema includes style, rsc, tsx, tailwind, iconLibrary, rtl, menuColor, menuAccent, aliases, and optional registries. Defaults are defined at validation time for several fields: rsc defaults to false, tsx defaults to true, Tailwind cssVariables defaults to true, the Tailwind prefix defaults to an empty string, menuColor defaults to default, and menuAccent defaults to subtle. The raw config is strict, so unexpected top-level fields are rejected instead of silently accepted.
Sources: packages/shadcn/src/registry/schema.ts
The resolved configuration adds resolvedPaths, including cwd, tailwindConfig, tailwindCss, utils, components, lib, hooks, and ui. This distinction is important for tooling: raw configuration captures what the user wrote, while resolved configuration captures normalized filesystem locations used during installation. The implementation also exposes workspaceConfigSchema as a record of resolved configs. A source comment notes that the key is not yet strongly typed to avoid a breaking change, which signals a compatibility choice in the public config surface.
Sources: packages/shadcn/src/registry/schema.ts
Files, Tailwind, CSS Variables, and CSS Blocks
Files are validated with a discriminated union on the type field. For registry:file and registry:page, target is required. For all other registry item types, target is optional. Every file record includes a path, may include inline content, and uses the registry item type system to communicate how the file should be treated. This rule protects ambiguous installs: pages and miscellaneous files often need explicit placement, while component, hook, lib, ui, theme, style, base, and font items can rely more on the registry and project conventions.
Sources: packages/shadcn/src/registry/schema.ts
Tailwind and design-token data have their own validation shapes. registryItemTailwindSchema allows an optional config object with optional content, theme, and plugins. registryItemCssVarsSchema supports separate theme, light, and dark string maps, matching the documented example where font-heading is added under theme and brand is declared for light and dark modes. This gives registry items a way to ship design-system tokens with code, instead of requiring users to discover and copy theme values from prose instructions.
Sources: apps/v4/content/docs/registry/registry-item-json.mdx, packages/shadcn/src/registry/schema.ts
The schema also defines a recursive CSS value structure for registry CSS blocks. A CSS value can be a string, an array containing strings or simple string records, or another nested record of CSS values. The comment in the source explains the intent: support CSS properties while allowing empty objects at any level. Combined with the February 2025 changelog, this shows the direction of the registry system: items are not limited to React components. They can distribute custom styles, tokens, animations, Tailwind layers, utilities, hooks, and themes as flat JSON that the CLI can apply.
Sources: apps/v4/content/docs/changelog/2025-02-registry-schema.mdx, packages/shadcn/src/registry/schema.ts
Public Schema Export
The public schema surface is intentionally thin. packages/shadcn/src/schema/index.ts re-exports everything from ../registry/schema, so consumers that import from the package schema entry point receive the same Zod schema definitions used by registry internals. That includes the registry config schemas, project config schemas, registry item type schema, file schema, Tailwind schema, CSS variables schema, and CSS schema visible in the implementation. This re-export is the source-backed public entry point for validation code that wants to align with the CLI instead of copying schema definitions by hand.
Sources: packages/shadcn/src/schema/index.ts, packages/shadcn/src/registry/schema.ts
Because the implementation comment says edits to the TypeScript schema must also be reflected in the generated public JSON schema file, maintainers should treat the Zod source and published JSON schema as a synchronized contract. Registry authors normally validate against the hosted JSON Schema URL in their files, while package consumers can use the exported Zod schemas programmatically. Both paths serve the same goal: keep authored registry content compatible with the CLI resolution and installation pipeline.
Sources: packages/shadcn/src/registry/schema.ts
Compact Reference
| Contract area | Concrete names and behavior |
|---|---|
| Registry config namespace | Keys in registryConfigSchema must start with @, for example @v0 or @acme. |
| Registry URL template | registryConfigItemSchema accepts a string or object, but the URL must include {name}. |
| Advanced registry config | Object form supports url, optional params, and optional headers. |
| Raw project config | rawConfigSchema includes $schema, style, rsc, tsx, tailwind, iconLibrary, rtl, menuColor, menuAccent, aliases, and optional registries. |
| Resolved project config | configSchema adds resolvedPaths for cwd, Tailwind files, utilities, components, lib, hooks, and ui paths. |
| Public item types | registry:base, registry:block, registry:component, registry:font, registry:lib, registry:hook, registry:ui, registry:page, registry:file, registry:style, registry:theme, registry:item. |
| Internal item types | registry:example and registry:internal are present in the implementation for internal use. |
| File records | registry:file and registry:page require target; other file item types make target optional. |
| Design token maps | registryItemCssVarsSchema supports theme, light, and dark. |
| Public export | packages/shadcn/src/schema/index.ts re-exports ../registry/schema. |
Working With the Schema
When authoring a registry item, start from the documented registry-item.json example and fill in the identity fields before adding files or dependencies. Choose the narrowest public type that describes the item, because the resolver uses type information when deciding how content should land in a project. Add npm dependencies only when the installed code needs package manager changes, and use registryDependencies when another registry item should be installed as part of the same user-facing feature.
Sources: apps/v4/content/docs/registry/registry-item-json.mdx, packages/shadcn/src/registry/schema.ts
When maintaining schema code, update validation rules with the public contract in mind. A change to registryItemTypeSchema, file targeting behavior, Tailwind support, or CSS variable structure can affect existing registries and generated JSON schemas. Prefer validating registry content with the exported schema surface instead of duplicating local rules. Next, read the registry overview for the distribution model, the registry index page for discovery rules, and the build-and-publish guide for validating registry content before release.