Docs

Publish a registry

Share your own components and blocks. Anyone with the CLI can install them next to the kit.

How it works

A registry is a folder of static JSON files: one <item>.json per component or block, plus an index.json. There is no server and no account. Build it from your source with the CLI, host it anywhere that serves files, and people install from it with npx vamos-ui add, exactly like the Vamos UI registry at https://ui.vamos.ist/r.

npx vamos-ui registry build                      # components/, lib/, blocks/ → r/*.json
npx vamos-ui add github:acme/ui/stat-card        # what your users run

Folder layout

Write your items the way the kit is written: React 19, Tailwind CSS v4, semantic tokens, and kit imports from @vamos-ui/react.

acme-ui/
  registry.json                 # optional: name, homepage, titles, Vamos UI dependencies
  package.json                  # optional: version ranges for npm imports
  components/stat-card.tsx      # → item "stat-card" (component)
  components/trend-badge.tsx    # → item "trend-badge" (component)
  components/kanban/            # → item "kanban" (component, every file in the folder)
  lib/format-money.ts           # → item "format-money" (lib)
  blocks/kpi-board/page.tsx     # → item "kpi-board" (block, every file in the folder)

Each file directly in components/ or lib/ is one item; a sub-folder there is one item with all its files. Each folder in blocks/ is one block. Tests (*.test.*, *.spec.*), stories and .d.ts files are skipped. The description comes from the first /** … */ comment in the file.

registry.json

Everything is optional except homepage (item docs links point to it; --homepage works too). Entries in items override or add to what was discovered:

{
  "name": "acme-ui",
  "homepage": "https://acme.dev/ui",
  "version": "1.2.0",
  "items": [
    {
      "name": "stat-card",
      "title": "Stat card",
      "registryDependencies": ["card", "badge"],
      "tags": ["kpi", "dashboard"],
      "usage": "import { StatCard } from \"@vamos-ui/react/components/stat-card\";"
    },
    { "name": "helpers", "type": "lib", "files": ["utils/format.ts", "utils/dates.ts"] }
  ]
}

Build

npx vamos-ui registry build                 # current folder → ./r
npx vamos-ui registry build ./acme-ui --out ./acme-ui/public/r
npx vamos-ui registry build --dry-run       # check without writing
npx vamos-ui registry build --strict        # treat warnings as errors (CI)

The builder reads imports to fill in dependencies, validates every item against the published schema and stops on errors:

  • A relative import of another item's file becomes a ./<item> dependency.
  • A relative import of a file that is in no item is an error. Add the file to an item.
  • A bare import (lucide-react) becomes an npm dependency with the range from package.json. react, react-dom, next and tailwindcss are provided by the app and skipped.
  • A block that imports one of your components is rewritten to @vamos-ui/react/components/…, which the CLI maps to the user's alias, because blocks and components land in different folders.
  • Imports from @vamos-ui/react are not resolved for you: list the kit items you use in registryDependencies. The builder warns when you forget.

Item format

The same format as the Vamos UI registry, validated against https://ui.vamos.ist/r/schema.json. Unknown fields are rejected.

{
  "name": "stat-card",
  "type": "component",
  "title": "Stat card",
  "description": "A KPI tile with a trend badge.",
  "docs": "https://acme.dev/ui",
  "dependencies": ["lucide-react@^1.70.0"],
  "registryDependencies": ["card", "./trend-badge"],
  "files": [{ "path": "components/stat-card.tsx", "content": "…" }],
  "tags": ["kpi"]
}
FieldRules
nameLower-case letters, digits and dashes. Also the file name: r/<name>.json.
typecomponent and lib files go to the user's uiDir keeping their path; block files go to blocksDir/<name>/. (style is reserved for the kit.)
filesRelative paths, no .., with the full source as content.
dependenciesnpm names with a semver range or dist-tag. Git, file, link and URL specs are rejected.
registryDependenciesSee Dependencies.
optionalgroup, category, tags, usage, props, examples, guidance, shown by vamos-ui view.

Dependencies

EntryMeans
cardA Vamos UI kit item (from the user's configured registry).
./trend-badgeAnother item in your registry, next to this one (same host, repo, ref and folder).
@acme/chart-kitA namespaced item; the user maps @acme in vamos.json.
github:acme/charts/sparklineAn item in another GitHub repository.
https://acme.dev/r/x.jsonAny https URL.

Naming rules

  • Item names are unique within your registry and never reuse a kit name (button, card, data-table …). Prefer a product prefix: acme-stat-card.
  • Give files distinctive names (components/acme-stat-card.tsx) so they cannot collide with kit files such as components/card.tsx or lib/cn.ts. The CLI never lets a third-party item replace a file another item installed; such a file is reported and kept.
  • Export names are unique too: prefix sub-parts with the component name (StatCardValue, not Value).
  • Do not name your registry or items after Vamos UI, and do not use the Vamos UI logo for them.

Hosting

  1. GitHub, no setup

    Commit the built r/ folder to a public repository. Users install with github:owner/repo/<item>, which reads raw.githubusercontent.com/owner/repo/HEAD/r/<item>.json. Another folder or a tag: github:owner/repo/public/r#v1.2.0/<item>.

  2. GitHub Pages

    Build into the folder Pages serves and commit it, or build in a workflow:

    # .github/workflows/registry.yml
    on: { push: { branches: [main] } }
    permissions: { pages: write, id-token: write }
    jobs:
      deploy:
        runs-on: ubuntu-latest
        environment: github-pages
        steps:
          - uses: actions/checkout@v4
          - run: npx -y vamos-ui registry build --out site/r --strict
          - uses: actions/upload-pages-artifact@v3
            with: { path: site }
          - uses: actions/deploy-pages@v4

    Users then run npx vamos-ui add https://owner.github.io/repo/r/<item>.json.

  3. Any static host

    Upload the folder to Netlify, Vercel, Cloudflare Pages, S3 or your own server. It must be served over https; JSON is fetched by the CLI, so no CORS headers are needed. Keep the URL stable: it is recorded in the user's lock file and used by diff and upgrade.

Installing

npx vamos-ui add https://acme.dev/r/stat-card.json
npx vamos-ui add github:acme/ui/stat-card
npx vamos-ui add @acme/stat-card          # with "registries": { "@acme": "https://acme.dev/r/{name}.json" }
npx vamos-ui view github:acme/ui/stat-card
npx vamos-ui diff @acme/stat-card         # later: compare with the published version

Test before you publish: npx vamos-ui add ./acme-ui/r/stat-card.json installs from a local file, and plain http://localhost URLs are allowed for a local server.

What users see
Before writing, the CLI names your host and lists every file. Items are data: nothing in them is executed, npm packages they need install with --ignore-scripts, and an item that fails the schema is refused.

Checklist

  • Tokens only: no raw colours, palette classes or dark: variants. Run npx vamos-ui verify components blocks.
  • Works in every axis: theme, material, accent, density and font.
  • Relative imports between your files; no project aliases like @/.
  • Every kit item you import is in registryDependencies; every npm package has a range in package.json.
  • npx vamos-ui registry build --strict passes, and a fresh npx vamos-ui create app can add each item.

The CLI reference is on CLI & registry.