# Contributor handoff — shadcn-ui/ui

> Canonical page: https://codevetter.com/unpack/ui/agent-handoff

# Contributor handoff — shadcn-ui/ui

Scanned commit 98a1fe67b439324ddc857f47fbdce056600a4329 (2026-09-21). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Most work happens in packages/shadcn (the CLI) and apps/v4 (site + registry authoring). Read the entrypoint, the two big command actions, the resolver/fetcher layer, and the updater pipeline before editing. Build the CLI before running e2e. Respect the invariants: CSS writes last, registry context cleared in finally, globalThis.fetch in proxy.ts, generated public/r is not hand-edited, and components.json is user-owned.
- Read-first files: packages/shadcn/src/index.ts (command table), commands/init.ts + commands/add.ts (the two complex actions), utils/add-components.ts (install pipeline), registry/resolver.ts + registry/fetcher.ts + registry/builder.ts (fetch/addressing), registry/schema.ts (all zod contracts), utils/updaters/update-files.ts (write+transform). — [packages/shadcn/src/index.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/index.ts) [packages/shadcn/src/commands/init.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/commands/init.ts) [packages/shadcn/src/commands/add.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/commands/add.ts) [packages/shadcn/src/utils/add-components.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/utils/add-components.ts) [packages/shadcn/src/registry/schema.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/schema.ts)
- Dev loop: `pnpm install`; build CLI `pnpm --filter=shadcn build` (tsup); run CLI against local site `pnpm shadcn:dev` (REGISTRY_URL=http://localhost:4000/r, SHADCN_TEMPLATE_DIR=../../templates) after `pnpm v4:dev`; unit tests `pnpm shadcn:test` (vitest run in packages/shadcn). — [package.json](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/package.json) [packages/shadcn/package.json](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/package.json)
- E2e tests require the built dist and the v4 site: root `pnpm test` = `pnpm --filter=v4 registry:build` + start-server-and-test on http://localhost:4000 + `turbo run test`; packages/tests executes dist/index.js — editing src without rebuilding silently tests stale code. — [package.json](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/package.json) [packages/tests/src/utils/helpers.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/tests/src/utils/helpers.ts) [packages/shadcn/package.json](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/package.json)
- Conventions: zod schemas validate every external input (options schemas, registryItemSchema, rawConfigSchema); interactivity via `prompts`; output via logger/highlighter/spinner wrappers; errors are typed RegistryError subclasses with code/suggestion/context; deepmerge for config merges. — [packages/shadcn/src/registry/errors.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/errors.ts) [packages/shadcn/src/commands/init.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/commands/init.ts) [packages/shadcn/src/registry/fetcher.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/fetcher.ts)
- Import alias: packages/shadcn source imports use '@/src/...' resolved by tsconfig paths + vite-tsconfig-paths in vitest — keep new imports on the alias, not relative chains. — [vitest.config.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/vitest.config.ts) [packages/shadcn/vitest.config.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/vitest.config.ts) [packages/shadcn/src/commands/add.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/commands/add.ts)
- Trap: registry/proxy.ts must keep calling globalThis.fetch (not undici's) so msw interception works in tests; redirects are manual — don't replace with redirect:'follow' or private-registry headers will leak cross-origin. — [packages/shadcn/src/registry/proxy.ts#L84-153](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/proxy.ts#L84-L153)
- Trap: every command action must end with clearRegistryContext() in finally (headers/env live in AsyncLocalStorage); new commands that fetch registry items need the same discipline. — [packages/shadcn/src/commands/add.ts#L325-327](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/commands/add.ts#L325-L327) [packages/shadcn/src/commands/init.ts#L598-600](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/commands/init.ts#L598-L600) [packages/shadcn/src/registry/context.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/context.ts)
- Trap: write CSS last — updateCss is intentionally after updateFiles so file watchers rebuild once; preserve ordering when touching the updater pipeline. Also preserve the components.json FILE_BACKUP_SUFFIX backup/restore dance in init. — [packages/shadcn/src/utils/add-components.ts#L132-147](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/utils/add-components.ts#L132-L147) [packages/shadcn/src/commands/init.ts#L164-175](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/commands/init.ts#L164-L175)
- Do not hand-edit generated artifacts: apps/v4/public/r/**, registry/__index__.tsx, registry/bases/__index__.tsx, styles/<style>/ui/** are build-registry.mts outputs; edit authored sources under registry/bases, registry/styles/*.css, examples/, and registry/new-york-v4 instead. — [apps/v4/scripts/build-registry.mts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/apps/v4/scripts/build-registry.mts) [apps/v4/registry/new-york-v4/registry.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/apps/v4/registry/new-york-v4/registry.ts)
- Release flow: changesets (`pnpm release` = changeset version); publishing is `cd packages/shadcn && pnpm pub:beta|pub:rc|pub:next|pub:release`; release.yml auto-publishes prereleases for PRs labeled 'release: beta'/'release: rc'; commits use conventional-commit lint (.commitlintrc.json). — [package.json](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/package.json) [packages/shadcn/package.json](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/package.json) [.github/workflows/release.yml](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/.github/workflows/release.yml) [.commitlintrc.json](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/.commitlintrc.json)
- Env vars that matter: REGISTRY_URL (registry base), SHADCN_TEMPLATE_DIR (template lookup), SHADCN_GITHUB_URL (template repo override), GH_TOKEN/GITHUB_TOKEN (github: item auth), HTTPS_PROXY/HTTP_PROXY/ALL_PROXY (fetch proxying), plus .env* files loaded per-command for ${ENV} expansion. — [packages/shadcn/src/registry/constants.ts#L5-6](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/constants.ts#L5-L6) [packages/shadcn/src/templates/create-template.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/templates/create-template.ts) [packages/shadcn/src/registry/github-cli.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/github-cli.ts) [packages/shadcn/src/registry/proxy.ts#L4-11](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/proxy.ts#L4-L11) [packages/shadcn/src/utils/env-loader.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/utils/env-loader.ts)
- Schema parity: registry/schema.ts is published as shadcn/schema and imported by apps/v4 (registryItemSchema in build-registry.mts and the /init route) — changing item shape requires updating both sides and the 871 committed public/r artifacts via a rebuild. — [packages/shadcn/src/registry/schema.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/schema.ts) [apps/v4/scripts/build-registry.mts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/apps/v4/scripts/build-registry.mts) [apps/v4/app/(app)/(create)/init/route.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/apps/v4/app/(app)/(create)/init/route.ts)
- templates/* are outside the pnpm workspace (pnpm-workspace only includes apps/*+packages/*); after editing a template, scripts/sync-templates.sh syncs them — CI templates.yml validates them. — [pnpm-workspace.yaml](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/pnpm-workspace.yaml) [scripts/sync-templates.sh](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/scripts/sync-templates.sh) [.github/workflows/templates.yml](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/.github/workflows/templates.yml)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
