Universal shadcn-style registry service: init / add / list / diff / scan / build — fetch registry items and write files into your app (not into node_modules). Tailwind sees classes. Works for React, Svelte, Vue, Solid, Go Templ, Latte/Twig — via framework / runtime + path contracts.
Contract version: 2.0.0 · npm package: ui8kit@2.0.1 · digest: @ui8kit/registry@2.0.0
Full documentation (English):docs/README.md
Agents / maintainers:AGENTS.md · project hub: .project/README.md
| Start here | |
|---|---|
| Getting started | Install + first init/add |
| Commands | Complete CLI reference |
| Scenarios | React, Svelte, Templ, private CDN, publish, CI |
| Registry format | Item / index JSON contract |
registry (CDN / digest) → npx ui8kit add → {dir}/components/ui/...
→ {dir}/utils, lib, blocks, layouts, …
Codegen (separate) emits primitives; this CLI installs registry packages into app folders and can scan/build local registry artifacts for publishing.
- Node.js
>=20(or Bun) - A project with
package.json(created byinitif missing) - No hard requirement for Vite/React
Published digest: @ui8kit/registry@2.0.0 (/r on unpkg / jsDelivr).
Important (ui8kit@2.0.1):
registry:utilsis hidden fromadd/--alland is not pulled viaregistryDependenciesyet. Install utils throughinit(do not pass--skip-core). A CLI fix is planned; until then follow this recipe.
# Svelte example — omit --skip-core so core utils land under src/utils
bunx ui8kit@2.0.1 init --yes \
--framework svelte \
--runtime svelte \
--dir src \
--registry-url https://unpkg.com/@ui8kit/registry@2.0.0/r \
--strict-cdnConfirm: src/utils/cn.ts (and friends) exist. If the folder is empty, re-run init without --skip-core or fetch utils manually (see below).
After init, edit to pin CDN + runtime (example for Vite/Svelte under src/):
{
"contractVersion": "2.0.0",
"framework": "svelte",
"runtime": "svelte",
"typescript": true,
"globalCss": "src/app.css",
"dir": "src",
"aliases": {
"@": "./src",
"@/ui": "./src/components/ui",
"@/utils": "./src/utils"
},
"registry": "@ui8kit",
"registryUrl": "https://unpkg.com/@ui8kit/registry@2.0.0/r",
"registryVersion": "2.0.0",
"strictCdn": true,
"importStyle": "alias"
}Path remap note: bricks import ../../utils. Keep utils at {dir}/utils. If you want MentorYChat-style src/kit, set "paths": { "ui": "kit" } in config for documentation — in 2.0.1 paths is ignored when registry files set target (they still install under components/ui). Workaround: after add, move src/components/ui/* → src/kit/ and leave src/utils in place. Do not set "utils": "kit/utils" without rewriting imports.
bunx ui8kit@2.0.1 add button stack title text --runtime svelte --force
# or everything:
bunx ui8kit@2.0.1 add --all --runtime svelte --force--runtime svelte keeps .svelte + *.shared.ts + *.variants.json only.
Also install npm peers used by utils if missing:
bun add clsx tailwind-merge
# or: npm install clsx tailwind-merge# Download item JSON and write files[] into {dir} by each file.target
curl -sL https://unpkg.com/@ui8kit/registry@2.0.0/r/utils/utils.json
# → write each files[].content to src/{files[].target}Or with Node one-liner from app root (after init created src/):
node --input-type=module -e "import { mkdirSync, writeFileSync } from 'node:fs';import path from 'node:path';const item = await fetch('https://unpkg.com/@ui8kit/registry@2.0.0/r/utils/utils.json').then(r => r.json());for (const f of item.files) { const target = path.join('src', f.target); mkdirSync(path.dirname(target), { recursive: true }); writeFileSync(target, f.content); console.log('wrote', target);}"bunx ui8kit@2.0.1 init --yes --framework svelte --runtime svelte --dir src \
--registry-url https://unpkg.com/@ui8kit/registry@2.0.0/r --strict-cdn
bunx ui8kit@2.0.1 add button --runtime svelte --forceGo / PHP (kit on disk). Prefer with core utils unless you only need markup:
bunx ui8kit@2.0.1 init --yes --framework templ --runtime templ --dir internal \
--registry-url https://unpkg.com/@ui8kit/registry@2.0.0/r --strict-cdn
bunx ui8kit@2.0.1 add button --runtime templ --force| Path | Role | Registry type |
|---|---|---|
lib/ | low-level runtime helpers | registry:lib |
utils/ | shared helpers (cn, …) — required by primitives | registry:utils |
components/ | composites | registry:component / composite |
components/ui/ | primitives (codegen digest) | registry:ui |
blocks/ | page sections | registry:block |
layouts/ | chrome / shells | registry:layout |
variants/ | variant maps | registry:variants |
widgets/ | UI + behavior | registry:widget |
Safe remap intent (utils stay top-level under dir):
{
"dir": "src",
"paths": { "ui": "kit" }
}Avoid "utils": "kit/utils" until the CLI rewrites relative imports (not in 2.0.1).
See the filled example in New app — utils + UI. Private CDN:
{
"contractVersion": "2.0.0",
"framework": "react",
"runtime": "react",
"dir": "src",
"globalCss": "src/app.css",
"registryUrl": "https://cdn.example.com/ui8kit/r",
"registryVersion": "2.0.0",
"strictCdn": true
}--registry-url/registryUrlcdnBaseUrlsfrom config (replaces built-in defaults when set)- Built-in defaults (
unpkg/jsdelivrfor@ui8kit/registry@latest/r)
--strict-cdn + explicit URL → only that URL.
--registry-version rewrites @latest → @2.0.0 in URL templates when applicable.
bunx ui8kit init
bunx ui8kit init --yes --framework none --dir src
bunx ui8kit init --yes --framework templ --dir internal
bunx ui8kit init --registry-url https://unpkg.com/@ui8kit/registry@2.0.0/r --strict-cdnCreates ui8kit.config.json + canonical directories. Without --skip-core, pulls lib/utils/variants from the registry when present (this is how you get utils today).
bunx ui8kit add button
bunx ui8kit add button card --force
bunx ui8kit add --all --runtime svelte
bunx ui8kit add button --dry-run
bunx ui8kit add button --registry-url https://unpkg.com/@ui8kit/registry@2.0.0/r --strict-cdnInstall preserves nested paths (e.g. components/ui/button/Button.svelte), no basename flatten.
Runtime filter: when --runtime or config.runtime is set, only that stack’s files are written, plus shared brick assets (*.shared.ts, *.variants.json). Utils/lib items are installed in full when reachable. Items that declare a different item-level runtime field are skipped entirely.
# Multi-file brick on CDN → only Svelte + shared land on disk
bunx ui8kit add button --runtime svelteKnown gap: ui8kit add utils fails in 2.0.1 — use init core install or the manual fallback.
Same roles as v1; info --cdn shows resolved CDN order.
{
"name": "button",
"type": "registry:ui",
"digest": "2.0.0",
"dependencies": [],
"registryDependencies": ["utils", "slot"],
"files": [
{
"path": "ui/button/Button.svelte",
"target": "components/ui/button/Button.svelte",
"content": "..."
},
{
"path": "ui/button/button.variants.json",
"target": "components/ui/button/button.variants.json",
"content": "..."
}
]
}framework: "vite-react"→react|svelte| … |noneinitno longer requires Vite + React- Install paths use
{dir}/…+ optionalpathsremap - File install preserves relative structure (
target/ path), not basename-only - New types:
registry:utils,registry:widget - Config fields:
dir,runtime,cdnBaseUrls,contractVersion
- Author/kit digest published as registry JSON on a CDN base (
@ui8kit/registry) - Apps:
ui8kit init(with core) +ui8kit add --runtime … - Maintainers: pack codegen →
ui8kit build→ publishr/ - Tailwind
content/@sourcepoints at{dir}/**
npm install
npm run type-check
npm test
npm run build
npm run pack:check # dry-run tarball contents# npm publish # after npm login; runs prepublishOnlyMaintainer scripts (local fixtures, CDN probe): see scripts/README.md.
User & author guides: see docs/README.md.
Deferred CLI fixes / known issues: .project/known-issues.md.
MIT