One registry for every jengacore product.
We publish the jengacore theme, brand files and 92 components as a private shadcn registry. Mulisa, Msingi, the Finance Portal and Disputes install from it with the shadcn CLI they already use, so the four apps change together and never fork a primitive. Every item ships in two builds: Radix for apps on the new-york style and Base UI for apps on base-nova. The CLI picks the right one from each app's components.json.
1. Point the app at the registry.
Add the @jengacore namespace to components.json. Keep {style} in the URL: the CLI replaces it with the app's own style.
{
"registries": {
"@jengacore": {
"url": "https://ui.jengacore.com/r/{style}/{name}.json",
"headers": { "Authorization": "Bearer ${JENGACORE_REGISTRY_TOKEN}" }
}
}
}2. Give the CLI a token.
The registry JSON under /r/ needs a bearer token. Put it in the app's .env (never committed); the CLI reads it at install time. Ask the platform team for a token per team or per CI pipeline.
JENGACORE_REGISTRY_TOKEN=…3. Install the product bundle.
Each bundle installs the core kit (theme, fonts, brand files, the restyled shadcn components and the shared jengacore components) plus that product's components and a starter block. The jengacore Button, Badge, Table, Dialog, Sheet, Tabs and Card keep the shadcn API, so the shadcn components already in the app keep working on top of them.
| App | Repository | Style | Install |
|---|---|---|---|
| Mulisa | jengacore-aml | base-nova | npx shadcn@latest add @jengacore/mulisa |
| Msingi | msingi | base-nova | npx shadcn@latest add @jengacore/msingi |
| Finance Portal | jengacore-finance-portal | new-york | npx shadcn@latest add @jengacore/finance |
| Disputes | jengacore-disputes (packages/ui) | new-york | npx shadcn@latest add @jengacore/disputes |
Install a bundle (or @jengacore/theme) by name the first time: the CLI then replaces the app's existing colour, font and radius variables. Installing a single component only adds the variables that are missing. The registry's helpers live in lib/jengacore/, so they never overwrite an app's own lib/format.ts or lib/status.ts.
The CLI asks before it replaces a file that already exists. Preview with --dry-run and --diff first, then pass --overwrite. The coverage page lists, app by app, what each existing component maps to.
npx shadcn@latest add @jengacore/finance --dry-run # list the files that would change
npx shadcn@latest add @jengacore/button --diff components/ui/button.tsx
npx shadcn@latest add @jengacore/finance --overwrite
npx shadcn@latest add @jengacore/settlement-position # one item at a time
npx shadcn@latest search @jengacore # list what the registry offersnpx shadcn@latest mcp init lets Claude Code and other agents browse and install @jengacore items.Keeping apps up to date.
Registry items are copied into the app, not imported from a package, so an update is a re-install: run the bundle again with --dry-run and --diff, keep local changes that matter, then --overwrite. The registry is rebuilt from source on every deploy, so the docs, the previews and the JSON the CLI receives never drift apart.