Component register

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:

Bash
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

  1. Put the component under src/components/ui/ (primitives) or its feature directory.
  2. If it needs a stripped-down demo, add a preview to src/features/components/previews/.
  3. Write the Markdown entry. First fence is the snippet.
  4. 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.
  5. Run bun run test:registry. It builds the site, serves dist/client/r, and runs the real shadcn CLI against every published slug into a temp directory. If the install breaks for a stranger, it breaks here first.