# Data flow — shadcn-ui/ui

> Canonical page: https://codevetter.com/unpack/ui/data-flow

# Data flow — shadcn-ui/ui

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

Input boundaries are CLI args, components.json (cosmiconfig), env files (.env*), and registry item JSON fetched over HTTP(S)/local disk/GitHub. Zod schemas validate all external data. Resolution turns item addresses into URLs via per-registry templates with {name}/{style} placeholders and ${ENV} expansion; resolveRegistryTree recursively merges items+dependencies into one install tree. Updaters then write package.json deps, tailwind config, env files, fonts, transformed source files, and finally CSS. The website's build-registry.mts is the upstream producer of the JSON the CLI consumes.
- Config input: a cosmiconfig explorer (searchPlaces: ['components.json']) loads raw config, rawConfigSchema validates, then resolveConfigPaths resolves tsconfig/jsconfig path aliases (components/ui/lib/hooks/utils) into resolvedPaths — tsconfig load failure throws. — [packages/shadcn/src/utils/get-config.ts#L26-116](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/utils/get-config.ts#L26-L116)
- Item address resolution order in fetchRegistryItems: github: scheme → fetchGitHubRegistryItem; local file → fetchRegistryLocal (with ~ expansion, zod parse); URL → fetchRegistry+parse; '@ns/item' → resolveRegistryItemsFromRegistries; bare name → `styles/{config.style ?? 'new-york-v4'}/{name}.json` under REGISTRY_URL. — [packages/shadcn/src/registry/resolver.ts#L81-133](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/resolver.ts#L81-L133) [packages/shadcn/src/registry/fetcher.ts#L143-176](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/fetcher.ts#L143-L176)
- Registry URL building substitutes {name} and {style} placeholders, expands ${ENV_VAR} via expandEnvVars (from AsyncLocalStorage registry env context), appends configured query params, and builds auth headers that are dropped if expansion leaves them empty. — [packages/shadcn/src/registry/builder.ts#L58-146](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/builder.ts#L58-L146) [packages/shadcn/src/registry/env.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/env.ts) [packages/shadcn/src/registry/context.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/context.ts)
- HTTP fetch path: fetchRegistry → resolveRegistryUrl (v0 /chat/b/ URLs get /json suffix; relative paths prefixed with REGISTRY_URL) → fetchWithProxy (manual redirect loop, SOCKS via ALL_PROXY, EnvHttpProxyAgent for HTTP(S)_PROXY, per-origin header re-scoping) → status-mapped errors (401/403/404/410) → response.json(). — [packages/shadcn/src/registry/fetcher.ts#L26-127](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/fetcher.ts#L26-L127) [packages/shadcn/src/registry/builder.ts#L155-168](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/builder.ts#L155-L168) [packages/shadcn/src/registry/proxy.ts#L93-173](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/proxy.ts#L93-L173)
- resolveRegistryTree recursively resolves registryDependencies (re-rewriting @namespaced deps through the registries config, erroring RegistryNotConfiguredError when unset) and merges each item's files/cssVars/css/envVars/dependencies/devDependencies/fonts into a single install tree validated by registryResolvedItemsTreeSchema. — [packages/shadcn/src/registry/resolver.ts#L148-200](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/resolver.ts#L148-L200) [packages/shadcn/src/registry/schema.ts#L272](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/schema.ts#L272)
- Install pipeline: addComponents → getWorkspaceConfig decides monorepo path (addWorkspaceComponents routes files to ui/hooks/lib workspace targets) vs addProjectComponents; both run resolveAndValidateRegistryTree → massageTreeForFonts → updateDependencies → updateTailwindConfig → updateEnvVars → updateFonts → updateFiles → updateCss (CSS written last so watchers rebuild after files land). — [packages/shadcn/src/utils/add-components.ts#L53-152](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/utils/add-components.ts#L53-L152) [packages/shadcn/src/utils/add-components.ts#L154-392](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/utils/add-components.ts#L154-L392)
- File writing: updateFiles resolves each file's target path (alias-aware, src-dir aware, --path override), skips identical content via isContentSame, merges .env files instead of overwriting, and runs the transformer chain: transformImport, transformRsc, transformCssVars, transformTwPrefixes, transformIcons, transformMenu, transformAsChild, transformRtl, conditional transformNext (Next 16 middleware), transformFont, transformCleanup. — [packages/shadcn/src/utils/updaters/update-files.ts#L107-220](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/utils/updaters/update-files.ts#L107-L220)
- Env input boundary: loadEnvFiles loads .env.local, .env.development.local, .env.development, .env from cwd via @dotenvx (no overload) so private-registry ${ENV} placeholders in URLs/headers/params resolve at fetch time. — [packages/shadcn/src/utils/env-loader.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/utils/env-loader.ts) [packages/shadcn/src/registry/env.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/env.ts) [packages/shadcn/src/commands/add.ts#L75](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/commands/add.ts#L75)
- components.json write path (init): existing config (or backup) is deepmerged with new config; discovered registries are appended (built-ins filtered out); registry:base config merged last; design settings (menuColor/menuAccent/rtl/iconLibrary) are propagated into each workspace package's components.json; file written with 2-space JSON. — [packages/shadcn/src/commands/init.ts#L713-823](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/commands/init.ts#L713-L823)
- Registry production: authored sources live in apps/v4/registry/bases/{base,radix,aria} plus registry/styles/style-*.css; build-registry.mts builds STYLE_COMBINATIONS (base × style), invokes the shadcn CLI to export public/r/styles/<style>/*.json, emits ui-rtl variants for nova styles, and formats outputs. — [apps/v4/scripts/build-registry.mts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/apps/v4/scripts/build-registry.mts) [apps/v4/registry/styles](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/apps/v4/registry/styles) [apps/v4/registry/bases](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/apps/v4/registry/bases)
- Dependency writes: updateDependencies resolves the package manager (npm/pnpm/yarn/bun/deno/expo special-cased) and execa's an install of registry-declared dependencies/devDependencies; React 19 + npm triggers a peer-deps warning pointing at ui.shadcn.com/react-19. — [packages/shadcn/src/utils/updaters/update-dependencies.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/utils/updaters/update-dependencies.ts)
- In-process caching: fetchRegistry dedupes in-flight fetches in a module-level Map keyed by url + sha256 of sorted headers; registry headers themselves live in AsyncLocalStorage context set by setRegistryHeaders and cleared via clearRegistryContext in each command's finally. — [packages/shadcn/src/registry/fetcher.ts#L20-24](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/fetcher.ts#L20-L24) [packages/shadcn/src/registry/context.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/registry/context.ts) [packages/shadcn/src/commands/add.ts#L325-327](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/commands/add.ts#L325-L327)
- Init URL contract: the site's /init endpoint emits a registry:base item whose `config` field the CLI reads via resolveRegistryBaseConfig; the CLI also strips the 'track' param before fetching and force-sets the 'base' param on the first component URL. — [apps/v4/app/(app)/(create)/init/route.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/apps/v4/app/(app)/(create)/init/route.ts) [packages/shadcn/src/commands/init.ts#L558-578](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/commands/init.ts#L558-L578) [packages/shadcn/src/preset/presets.ts](https://github.com/shadcn-ui/ui/blob/98a1fe67b439324ddc857f47fbdce056600a4329/packages/shadcn/src/preset/presets.ts)

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)
