Install From VegaStack Registry
Configure shadcn to consume the private VegaStack Base UI registry.
Last updated
New project? Follow the Quickstart — the full zero-to-dashboard walkthrough. Building for a client? See Client projects. This page is the registry-setup reference the component pages link to; the Guides section covers auth, updates, theming, production readiness, and troubleshooting in depth.
VegaStack components are copy-in registry items. One public npm package provides the
runtime layer (utilities, icons, Tailwind preset, CLI); component source comes from the
private shadcn registry. Design tokens ship separately as the zero-dependency
@vegastack/design-tokens (installed automatically as a dependency of @vegastack/design).
Public Packages
Install the public layer first. It does not require VegaStack credentials.
npm install @vegastack/designImport the VegaStack preset in your app stylesheet. preset.css bundles Tailwind, the theme
tokens, the base a11y layer, and the utility helpers in one import.
@import "@vegastack/design/preset.css";Don't skip the base layer. The preset bundles the tokens'
base.css, which ships the global:focus-visiblering, theprefers-reduced-motionreset, pointer cursors, and portalisolation. By design, components carry no focus ring of their own — keyboard focus visibility (WCAG 2.4.7) comes from this layer. If you import@vegastack/design/theme.cssdirectly instead, you must also@import "@vegastack/design/base.css";, or focus rings disappear for shipped users.
Tokens without React? A non-Tailwind or non-React consumer (native app, token pipeline, marketing site) can install just the design contract:
npm install @vegastack/design-tokens— zero dependencies, pure CSS/JSON.
shadcn Base UI
Initialize shadcn with the Base UI implementation.
npx shadcn@latest init --base baseVerify the resolved project base before installing components.
npx shadcn@latest info --jsonThe result must report "base": "base". A Radix-resolved config is not a valid
VegaStack component consumer.
Registry Namespace
Internal consumers add the VegaStack namespace to components.json. Production
registry reads require Cloudflare Access service-token headers; browsing the public docs
does not authenticate /r/* registry access.
{
"registries": {
"@vegastack": {
"url": "https://design.vegastack.com/r/{name}.json",
"headers": {
"CF-Access-Client-Id": "${CF_ACCESS_CLIENT_ID}",
"CF-Access-Client-Secret": "${CF_ACCESS_CLIENT_SECRET}"
}
}
}
}The docs app dogfoods the same registry shape against a local server:
{
"registries": {
"@vegastack": {
"url": "http://localhost:4000/{name}.json"
}
}
}Integrity Preflight
Verify each registry item before copy-in, save the verified bytes, then verify the files
written by shadcn add. This is the fail-closed flow that closes the registry fetch
time-of-check/time-of-use gap.
VEGASTACK_VERIFY_DIR="$(mktemp -d "${TMPDIR:-/tmp}/vegastack-verify.XXXXXX")"
VEGASTACK_ITEM="$VEGASTACK_VERIFY_DIR/button.json"
npx --package=@vegastack/design vegastack-design verify \
--save "$VEGASTACK_ITEM" button
# Retain this before running shadcn so it remains independent of the saved file during copy-in.
VEGASTACK_EXPECTED_INTEGRITY="$(node -e \
'process.stdout.write(JSON.parse(require("node:fs").readFileSync(process.argv[1], "utf8")).meta.integrity)' \
"$VEGASTACK_ITEM")"The save path must be new; the verifier refuses to overwrite an existing file or follow a symlink.
Use --hash-only only for local development when the signed manifest or cosign is unavailable.
The full mode verifies the signed manifest identity and the item hash.
Add Components
After the namespace is configured and the preflight passes, install components by name.
pnpm dlx shadcn@latest add @vegastack/button
pnpm dlx shadcn@latest add @vegastack/fieldThen prove the copied files match the saved item bytes.
npx --package=@vegastack/design vegastack-design verify \
--post-write --item "$VEGASTACK_ITEM" \
--expected-integrity "$VEGASTACK_EXPECTED_INTEGRITY" --target-dir .The registry item installs its npm dependencies, registry dependencies, and source files. (The current shadcn CLI strips the stamped provenance header during copy-in — that's expected; update tracking identifies copies by filename and compares content, no header needed.)
Updating components
Registry components are copy-in — you own the copy, so updates are pulled, never pushed. Tracking is by content: copies are identified by filename against the registry index and compared alias-normalized (a provenance header, when present, is only a fast-path pin). One command shows what's stale against the live registry:
npx --package=@vegastack/design vegastack-design check-updates ⬆ button 0.1.0 → 0.2.0 update available
≈ card → 0.2.0 differs from registry (update or local edits — review with --diff)
✓ field 0.2.0 up to date
? legacy 0.1.0 not in registry (renamed/removed)Status is by content, so a component reads up to date even when the registry's global
version bumped but that component's content didn't change; ≈ means the bytes diverged —
an upstream update or your local edits. Review and apply per component:
npx shadcn@latest add @vegastack/button --diff # see exactly what changed
npx shadcn@latest add @vegastack/button --overwrite # take it (re-apply any local edits)--overwrite replaces the file, so git diff first if you customized it. For CI drift detection,
vegastack-design check-updates --fail-on-update exits non-zero when anything is stale. The CLI reads
the @vegastack registry URL + headers from components.json — ${ENV} placeholders expand from
.env.local / .env or the shell (same as shadcn), falling back to VEGASTACK_REGISTRY +
CF_ACCESS_*. Before attaching any credential it requires the exact trusted HTTPS origin
(https://design.vegastack.com by default) and rejects redirects. A custom credentialed registry
must set VEGASTACK_TRUSTED_REGISTRY_ORIGIN in operator-controlled process/CI configuration;
checkout-local dotenv cannot change that trust anchor.
External/client projects do not receive registry service tokens. VegaStack copies component source during development, and the shipped app remains self-contained.