Skip to content
Tennantite
中文
Documentation

Registry

How the shadcn registry endpoint and the full index are generated.

What a registry is

A registry is shadcn’s source-distribution format. This project produces two kinds of output:

  1. Installable endpoint https://tennantite.rikka.cc/r/<name>.json: one file per core component with all source inlined as content plus target, directly consumable by the shadcn CLI.
  2. Full index registry/registry.json: covers @tennantite/ui and every mod package (311 entries) for catalog and documentation reference; mod entries keep path only and do not participate in CLI copying.

Generate

pnpm registry
# Equivalent to
node registry/build.mjs

Coverage

The installable endpoint covers 5 component groups inside @tennantite/ui (primitives, containers, screens/containers, screens/hud, screens/menus) — 63 component items — plus tennantite-base and 4 shared items:

  • tennantite-base: only declares the @tennantite/tokens and @tennantite/textures npm dependencies and drops a base.css recording the asset CSS to import; the CLI installs it alongside the first component you add.
  • tennantite-utils: shared cn and gui helpers, placed at components/tennantite/lib/tennantite-utils.ts without touching your own @/lib/utils.
  • screen-types: shared screen types such as ScreenSlot and padSlots.
  • screen-parts / screen-slot: shared slot and part components used by container screens.

Mod packages (mekanism, ic2, ae2, …) are outside the CLI copy scope: they import heavily through the @tennantite/ui barrel, which makes copy-and-rewrite disproportionately expensive. They keep the pnpm add @tennantite/<mod> npm-install mode.

Consuming it

Option 1: configure a namespace registry in components.json and install by name:

{
  "registries": {
    "@tennantite": "https://tennantite.rikka.cc/r/{name}.json"
  }
}
npx shadcn add @tennantite/button

Option 2: direct URL, no configuration needed:

npx shadcn add https://tennantite.rikka.cc/r/button.json

Item shape

Every item inlines its source so the CLI never resolves repo paths:

{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "card",
  "type": "registry:component",
  "dependencies": ["cn"],
  "registryDependencies": ["@tennantite/tennantite-base", "@tennantite/panel", "@tennantite/title-bar"],
  "files": [
    {
      "content": "import { Panel } from \"@/components/tennantite/panel\";\n// …",
      "target": "components/tennantite/card/index.tsx",
      "type": "registry:component"
    }
  ]
}

Import rewrite rules

For every inlined file the generator rewrites imports with these rules (a failed rewrite aborts the build instead of producing a broken item):

  • Relative imports resolving inside the component’s own directory (./types, ./styles) are kept as-is.
  • Imports pointing at another component directory (e.g. ../panel/index) become @/components/tennantite/panel and are recorded in registryDependencies.
  • Imports of lib/utils.ts and shared screen types become @/components/tennantite/lib/tennantite-utils and @/components/tennantite/lib/screen-types.
  • @tennantite/textures is kept untouched and appended to the item’s npm dependencies.

Every entry in registryDependencies automatically gains @tennantite/tennantite-base, so the L0 asset packages (tokens/textures) are installed on first add. Cross-item dependencies must be fully namespaced (@tennantite/<name>); unqualified names are resolved against the official shadcn registry by the CLI.