Docs Surfaces
Component register
How /components is assembled, and how a piece is published to the shadcn registry at /r.
/components is a register of the interactive pieces this site is built from. Each
one is a live specimen — not a screenshot — and most of them can be installed into
another project with one command.
The two halves
The surface is split, and the split matters because the two halves have different jobs:
/components— a bento grid of live tiles. It exists to be looked at. Tiles link to their detail page; some are iframed because they take over scroll or use fixed positioning and would otherwise fight the page around them./components/<slug>— one specimen, its usage snippet, its install command, and a link to the source.
An entry
One Markdown file per component in src/content/components/. The filename is the
slug, so decode-text.md becomes /components/decode-text and registry name
decode-text. The schema lives in src/content.config.ts:
| Field | Meaning |
|---|---|
title |
Display name. |
tagline |
One line, shown under the title and in the grid caption. |
tier |
primitive, showpiece, or composition. Ordering and framing. |
order |
Sort key within a tier. |
install |
{ type: 'registry' } or { type: 'npm', pkg: '...' }. |
source |
Absolute URL to the source on GitHub. |
credits |
Optional attribution line. |
draft |
Hides the entry everywhere, including the registry. |
The body’s first fenced code block is the usage snippet. Nothing else in the body is special — write what a reader needs after the snippet.
Tiers
primitive is a base UI piece (button, badge, card) that other things are built
out of. showpiece is a self-contained specimen with its own behavior — the
decode-text engine, the mood wheel. composition is several pieces wired
together into a working block. The tier decides how the detail page frames the
specimen and where it falls in the ordering, not what the component can do.
The registry
Entries with install.type === 'registry' are also published as shadcn registry
items at build time, by src/pages/r/[name].ts:
bunx shadcn@latest add https://buxx.me/r/decode-text
The item is assembled by
src/features/components/server/registry.ts,
which reads the real source files off disk — so a registry item can never drift
from the component running on this page. It emits a
registry-item.json-conforming object with files, dependencies,
registryDependencies, and any cssVars the piece needs in both modes. A
utils item is published alongside so cn() resolves.
Routes are prerendered, so the registry is static JSON on the CDN — there is no runtime component to keep alive.
Adding one
- Put the component under
src/components/ui/(primitives) or its feature directory. - If it needs a stripped-down demo, add a preview to
src/features/components/previews/. - Write the Markdown entry. First fence is the snippet.
- For a registry publish, register the file list in
registry.ts— nothing is inferred, and that is deliberate: a component’s public file set is a decision, not a directory listing. - Run
bun run test:registry. It builds the site, servesdist/client/r, and runs the realshadcnCLI against every published slug into a temp directory. If the install breaks for a stranger, it breaks here first.