Guides · October 18, 2023
What Is a shadcn Registry (and Why It's the New Theme Store)
A shadcn registry is a JSON-described catalog of components, hooks, and blocks that the shadcn CLI can install directly into your codebase as owned source files. It works like a theme store, except you get editable code instead of a locked-down template.
By Polo Themes
A shadcn registry is a structured catalog — a set of JSON files following the registry.json and registry-item.json schema — that describes components, blocks, hooks, and CSS variables so the shadcn CLI can pull them straight into your project's source tree. Instead of installing a package from npm and importing it as a black box, you run a single "npx shadcn add" command and get real, editable component files sitting in your own components folder, wired to your own Tailwind config. That distinction — distribution as source rather than distribution as a dependency — is why registries are quietly becoming the new theme store for anyone building with React, Next.js, or any modern component-driven stack.
This matters more than it sounds like on first read. For fifteen years, "buying a theme" has meant buying a bundle of compiled output you were expected to leave alone — a WordPress zip, a Shopify Liquid theme, a locked Figma file you traced by hand. A registry flips that relationship. The thing you install is the thing you edit. This post is a deep, practical walkthrough of what a registry actually is, how the protocol works under the hood, why it is a genuinely better distribution model for design assets, and where it fits next to the Figma-to-code and headless-commerce work most modern teams are already doing.
The Short Version: Registries Distribute Source, Not Packages
shadcn/ui popularized a distribution pattern that is worth naming clearly, because the naming is where a lot of confusion starts. shadcn/ui is not a component library in the traditional sense — there is no single npm package you import components from. It is a CLI plus a protocol. The CLI reads a registry — which can be the public shadcn registry or any custom one you point it at — resolves a component's dependencies (other components, npm packages, Tailwind config, CSS variables), and then copies the actual source code into your repository at a path you control.
Once that copy happens, the registry's job is done. You now own a Button component or a PricingCard component exactly the way you'd own a file you wrote yourself. There is no version to bump, no breaking change to absorb on your schedule, no dependency boundary hiding the implementation from you. If you want to change a hover state, swap an icon, or restructure a layout, you open the file and edit it. This is the single fact that explains almost everything else interesting about registries.
Anatomy of a Registry: What's Actually in the JSON
A registry is, at its core, two kinds of JSON documents. A registry.json file at the root describes the whole catalog — its name, its homepage, and an index of every item it contains. Each individual registry-item.json (or an inline entry in that index) describes one installable unit: a component, a block, a hook, a UI page template, or even a set of CSS custom properties for theming. A typical item entry carries:
- name and type — for example a component, a block, a hook, a library file, or a full page, telling the CLI what kind of file it's writing and where it conventionally belongs.
- files — an array of path, content, type, and target values. This is the actual source code, plus the target path in the consuming project (so a block can drop a page under an app route and a component under a shared components folder).
- registryDependencies — other items from the same (or a different) registry that must be installed first, letting a complex block pull in a dozen primitive components automatically.
- dependencies and devDependencies — plain npm packages the code needs, which the CLI installs with your project's package manager.
- cssVars and Tailwind config fragments — design tokens (colors, radii, spacing) that get merged into your global stylesheet and Tailwind config so the component's look ships with the component, not as a separate manual step.
That last point is worth sitting with. A registry item doesn't just hand you markup — it can carry its own token contract, so installing a themed block also installs the CSS variables that make it look right. That's a meaningfully different unit of distribution than a component library plus a separate theming guide you have to reconcile by hand.
Public, Private, and Team-Internal Registries
Because the registry format is an open JSON schema and the CLI accepts any URL that serves it, "the shadcn registry" has stopped meaning one specific catalog. There are now three distinct patterns worth knowing:
The public shadcn/ui registry
The original, canonical set of accessible primitives — button, dialog, dropdown, form, table, and so on — built on Radix UI primitives and Tailwind CSS. This is what most people mean when they say "shadcn" casually, and it's the default target when you run the CLI without pointing it elsewhere.
Third-party and community registries
Because the protocol is open, anyone can publish a registry — a marketing-block library, an admin-dashboard kit, an animation-heavy component set — and users install from it with the exact same install command they already know, just pointed at a different URL. This is the part that most resembles a theme marketplace: independent creators shipping themed, opinionated components through a shared, standardized installer, rather than each vendor inventing its own bespoke setup script.
Private, internal design-system registries
The pattern that's spreading fastest inside real product teams is a private registry hosted behind auth, serving a company's own design system as installable components. Instead of a shared internal npm package that every team has to import and version-bump in lockstep, a design-systems team publishes a registry; each product team runs the CLI, gets the current source dropped into their app, and can diverge locally when a screen genuinely needs a one-off tweak — without forking a package or filing a ticket to get a prop added upstream.
Why Source Distribution Beats Package Distribution for UI
It's worth being precise about why this model is winning, because "just copy the code in" sounds almost too simple to be a real architectural decision. A few concrete reasons hold up under scrutiny:
- No abstraction tax on customization. A traditional component library forces every customization through its public API — props, theme objects, CSS-in-JS overrides, specificity battles. When the component is your own file, "customize it" just means "edit it." There is no ceiling on how deep a change can go.
- No version-lock dependency hell. Traditional libraries eventually force an upgrade that changes a prop name or a default style across your whole app at once. Copied source is frozen at the moment you installed it — you upgrade a component deliberately, one at a time, by re-running the CLI, not because a semver bump forced your hand.
- Full transparency for AI-assisted development. This is the one that's changed the calculation most in the last two years. When a component is a file in your repo, an AI coding assistant can read it, understand its actual implementation, and modify it directly. When a component is compiled output hidden inside a dependency, the assistant is reasoning about a black box and can only suggest wrapper hacks. Source-first distribution is dramatically more compatible with AI-native and agentic workflows — the model can see and edit the real thing, not a proxy for it.
- Bundle size stays honest. You only ship the code paths you actually installed and kept. There's no dead-code-elimination step trying to tree-shake out the majority of a monolithic library you never touch — you never had it in the first place.
- The design system is legible, not magical. New engineers can open a component and read exactly how it's built, rather than reverse-engineering a theming API through trial and error. This lowers onboarding cost for a design system in a way that's easy to underrate until you've lived through the alternative.
The MCP Angle: Registries as a Machine-Readable Interface
The other reason registries matter right now is that the JSON schema behind them is exactly the kind of structured, machine-readable interface that fits naturally into Model Context Protocol (MCP) tooling and AI-driven scaffolding. An MCP server — or any agentic coding tool — can query a registry's index, reason about which block satisfies a given brief ("give me a pricing section with three tiers and a toggle"), fetch the item's JSON, and generate a working page by composing registry items rather than hallucinating component code from scratch. The registry becomes a grounded, versioned source of truth the model can call into, instead of a fuzzy memory of what shadcn components generally look like.
That's a structurally different and more reliable pattern than asking a model to freehand a component from a text description. It's also why "registry" is becoming a load-bearing concept for AI-native design tooling generally, not just a shadcn-specific implementation detail — expect the same source-distribution-plus-machine-readable-manifest shape to show up anywhere design-to-code and agentic development intersect over the next few years, whether the underlying stack is React, Vue, or something newer.
Building a Custom Registry: The Practical Shape
If you're standing up your own — for a design system, a themed component pack, or an internal pattern library — the shape is more approachable than it looks from the outside. At minimum you need:
- A registry.json index listing every item's name, type, and where its files live.
- One registry-item.json (or inline block) per component or block, with its files array containing real source and correct target paths.
- Any shared CSS variables or Tailwind theme fragments declared once, so consumers get consistent tokens across every item they install rather than a different color per block.
- A place to host it — a static JSON endpoint is sufficient; the CLI just needs a URL pointing at each item's JSON to resolve it.
- A validation pass against the official schema before publishing, so a malformed item doesn't silently fail to install for someone three teams away from you.
The shadcn CLI also ships a build command for generating a full registry's JSON output from a source directory of components, which is the more common real-world starting point than hand-writing every item's JSON from scratch — you write normal React components, annotate dependencies, and let the tool produce the distributable manifest.
Where This Fits Next to Figma-to-Code and Headless Commerce
It's worth being honest about where the registry model sits relative to the design and commerce work teams are actually doing today, because it's a complement, not a replacement, for most of it. Design-to-code pipelines that start in Figma and translate visual specs into production code are solving a different half of the problem than registries do — Figma work defines the visual and interaction intent; a registry defines how the resulting code gets distributed and re-distributed once it exists. A well-run team increasingly wants both: source components meticulously designed in Figma (browsing a curated set like our Figma UI kits is a reasonable way to see what disciplined, developer-handoff-ready design source looks like), then made installable as registry items so every consuming app gets the current version as real, editable code rather than a static export.
The same complementary relationship holds for headless commerce. Storefronts built on Next.js against a headless commerce backend — Medusa, Shopify's Storefront API, or similar — increasingly assemble their UI from installable component sets rather than a single monolithic theme file, because a registry item can be swapped, audited, and upgraded independently of the checkout logic sitting behind it. None of this requires abandoning a Shopify OS 2.0 storefront if that's what a merchant already runs successfully — theme-based and headless-plus-registry approaches are different tools for different scale and flexibility requirements, not a strict upgrade path from one to the other.
Where does that leave a company like ours today? Polo Themes currently builds and sells Figma UI kits and Shopify OS 2.0 themes — real, finished products, not a registry. We think the registry model described in this post is a genuinely important direction for how component-based design assets will be distributed going forward, and we're watching it closely as part of our own roadmap. That's a statement about where the industry is heading, not a claim that we ship a registry today — if and when we do, it'll be announced on its own terms rather than folded quietly into an unrelated post.
A Simple Mental Model to Keep
If you only remember one distinction from all of this: a package is something you depend on, and a registry item is something you own. A package gives you a promise that an API will keep working across versions, in exchange for giving up control over the implementation. A registry item gives you the implementation itself, in exchange for taking on the responsibility of maintaining your own copy. Neither is universally correct — a design token library that truly should stay centrally governed is often better as a real package — but for the vast majority of UI components, where teams inevitably want to nudge spacing, swap an icon, or restructure a card layout, owning editable source has turned out to be the more honest and more durable choice. That's the shift a shadcn registry actually represents, and it's why "browse the registry" is quickly becoming as natural a phrase as "browse the theme store" used to be. If you want to see how far a disciplined, source-first design catalog can go on the design side alone, our Figma UI kits catalog and the rest of our full theme library are a reasonable place to start looking.
Frequently Asked Questions
Is a shadcn registry the same thing as an npm package?
No. An npm package is imported and lives as a dependency you upgrade over time. A registry item is copied into your own source tree by the CLI and becomes a file you own and edit directly — there is no ongoing dependency relationship after the install.
Can I use a shadcn registry with plain React, or only Next.js?
The CLI and registry format work with any React setup that uses Tailwind CSS — Next.js, Vite, Remix, and others are all supported starting points. Next.js is simply the most common pairing because of how naturally the App Router's file conventions match registry block targets like page templates.
Do I need to know the internals of a registry to use one?
No — most developers only ever run the install command for a given component and never look at the underlying JSON. Understanding the schema matters mainly if you're publishing your own registry or debugging why an install pulled in unexpected dependencies.
Does adopting a registry model mean abandoning Figma or a Shopify theme?
Not at all. Registries are a code-distribution mechanism, not a design tool or a commerce platform. Figma remains where visual and interaction design gets defined, and a Shopify theme remains a perfectly valid, proven storefront approach for merchants who don't need a headless, component-registry-based build. They solve different problems and can coexist in the same team's toolkit.