This guide covers the complete internals of shadcn/ui (v4.3.0) — a CLI-driven component registry system that copies React UI component source code directly into your project. Unlike traditional component libraries installed as npm dependencies, shadcn/ui fetches component files from a remote registry, applies a chain of AST-based transforms to match your project's configuration, and writes the results into your source tree. You own the code from the moment it lands.
The system is organized as a pnpm monorepo managed by Turborepo. The primary deliverable is the shadcn npm package (a CLI tool), accompanied by a Next.js documentation website, integration test suites, and project scaffolding templates for ten framework configurations. Components are built on either Radix UI (v1.4.3) or Base UI (@base-ui/react v1.3.0) primitives and styled with Tailwind CSS 4.x.
This document is written for administrators deploying custom registries, developers contributing to the codebase, and architects evaluating the system's design. Written from source code.
1. Architecture Overview
1.1 What the System Does
shadcn/ui solves a specific problem in the React ecosystem: developers want pre-built, accessible UI components but also want full control over the source code. Traditional npm-installed libraries create a dependency you cannot easily customize. shadcn/ui flips this model — the shadcn CLI fetches component source from a registry, rewrites imports and styles to match your project's aliases and configuration, then writes the files directly into your codebase. After that, the CLI is no longer involved; the components are yours to modify.
The registry system supports multiple "bases" (Radix UI and Base UI), multiple style variants, icon library swapping, RTL transforms, CSS variable theming, Tailwind prefix handling, and monorepo-aware file routing. A preset system allows encoding an entire design configuration into a compact string or named preset, enabling one-command project setup.
The CLI also implements the Model Context Protocol (MCP), allowing AI coding tools (Claude Code, Cursor, VS Code Copilot, Codex, OpenCode) to programmatically add components to projects.
1.2 Component Inventory
| Component | Path | Role |
|---|---|---|
| CLI Package | packages/shadcn/ |
Published npm package; all user-facing commands |
| Documentation Website | apps/v4/ |
Next.js 16 site with MDX docs and live examples |
| Component Registry Source | apps/v4/registry/ |
Source files for all registry components |
| Integration Tests | packages/tests/ |
End-to-end tests that build registry + run CLI |
| Project Templates | templates/ |
Scaffolding templates for 10 framework configurations |
| AI Agent Skills | skills/shadcn/ |
Rules and instructions for AI agents |
1.3 Technology Stack
| Layer | Technology | Version |
|---|---|---|
| Language | TypeScript (ESM) | — |
| CLI Framework | Commander.js | — |
| Build (CLI) | tsup | — |
| Build (Monorepo) | Turborepo | — |
| Package Manager | pnpm | 9.0.6 |
| UI Primitives | Radix UI | 1.4.3 |
| UI Primitives (alt) | Base UI (@base-ui/react) |
1.3.0 |
| Styling | Tailwind CSS | 4.x |
| Validation | Zod | — |
| Config Loading | cosmiconfig | — |
| Website Framework | Next.js | 16.1.6 (Turbopack) |
| Documentation Engine | Fumadocs (MDX) | — |
| Testing | Vitest | — |
| Code Transform | Babel, ts-morph 26.0, recast | — |
| HTTP Client | node-fetch + https-proxy-agent | — |
| MCP Server | @modelcontextprotocol/sdk | — |
| Charts | Recharts | 3.8.0 |
| State Management | Jotai, nuqs | — |
| Package Publishing | Changesets | — |
1.4 Data Flow
The core operation — adding a component — follows this pipeline:
User runs: npx shadcn add button
│
▼
┌─────────────────────┐
│ 1. Config Loading │ cosmiconfig reads components.json
│ (get-config) │ Validates against Zod schema
└─────────┬───────────┘
▼
┌─────────────────────┐
│ 2. Pre-flight │ Check framework, TypeScript, Tailwind,
│ Checks │ package manager, RSC support
└─────────┬───────────┘
▼
┌─────────────────────┐
│ 3. Registry │ Fetch item from https://ui.shadcn.com/r
│ Resolution │ Recursively resolve all dependencies
└─────────┬───────────┘
▼
┌─────────────────────┐
│ 4. Transform │ 9-stage pipeline rewrites each file:
│ Pipeline │ imports → RSC → CSS vars → TW prefix →
│ │ icons → menu → RTL → font → cleanup
└─────────┬───────────┘
▼
┌─────────────────────┐
│ 5. Write Phase │ Validate targets (isSafeTarget)
│ │ Update dependencies (npm/pnpm/yarn/bun)
│ │ Update tailwind config
│ │ Update env vars
│ │ Update fonts
│ │ Write transformed files
│ │ Update CSS (last — triggers rebuild)
└─────────────────────┘
2. System Requirements
2.1 Runtime Requirements
| Requirement | Minimum | Notes |
|---|---|---|
| Node.js | >= 20 | Required for ESM support and native fetch |
| Package Manager | pnpm 9.0.6, npm, yarn, or bun | pnpm required for monorepo development; users may use any supported manager |
| Git | Any recent version | Required for shadcn init post-init step |
| Operating System | macOS, Linux, Windows | Node.js cross-platform |
2.2 Supported Frameworks
The CLI detects and supports these frameworks via the project detection system in packages/shadcn/src/utils/get-project-info.ts:
| Framework | Template Variants |
|---|---|
| Next.js | Single app, Monorepo |
| Vite (React) | Single app, Monorepo |
| React Router | Single app, Monorepo |
| TanStack Start | Single app, Monorepo |
| Astro | Single app, Monorepo |
Note
Framework detection examines
package.jsondependencies, configuration files (e.g.,next.config.js,vite.config.ts,astro.config.mjs), and directory structure to determine the active framework. The detection is automatic duringshadcn init.
2.3 Development Requirements
For contributing to the shadcn/ui monorepo itself:
| Requirement | Detail |
|---|---|
| pnpm | 9.0.6 (enforced via packageManager field) |
| Node.js | >= 20 |
| Turbo | Installed via pnpm (devDependency) |
| Disk Space | ~2 GB (node_modules across all workspaces) |
3. Configuration Reference
3.1 components.json — Complete Schema
The components.json file is the project-level configuration for shadcn/ui. It is created by shadcn init and read by every subsequent command via cosmiconfig. The schema is validated by Zod in packages/shadcn/src/schema/.
| Field | Type | Default | Description |
|---|---|---|---|
$schema |
string |
"https://ui.shadcn.com/schema.json" |
JSON Schema URL for editor autocompletion |
style |
string |
— | Active style variant name (e.g., "new-york-v4") |
rsc |
boolean |
— | Whether the project uses React Server Components |
tsx |
boolean |
— | Whether to output .tsx files (false = .jsx) |
tailwind.config |
string |
— | Path to Tailwind config file |
tailwind.css |
string |
— | Path to the global CSS file |
tailwind.baseColor |
string |
— | Base color for theming (e.g., "zinc", "slate") |
tailwind.cssVariables |
boolean |
— | Whether to use CSS custom properties for theming |
tailwind.prefix |
string |
"" |
Tailwind class prefix (e.g., "tw-") |
aliases.components |
string |
— | Import alias for components (e.g., "@/components") |
aliases.utils |
string |
— | Import alias for utility functions |
aliases.ui |
string |
— | Import alias for UI components (defaults to {components}/ui) |
aliases.lib |
string |
— | Import alias for lib directory |
aliases.hooks |
string |
— | Import alias for hooks directory |
iconLibrary |
string |
— | Icon library identifier (e.g., "lucide", "icons") |
rtl |
boolean |
false |
Enable right-to-left layout transforms |
menuColor |
string |
"default" |
Menu color variant: "default", "inverted", "default-translucent", "inverted-translucent" |
menuAccent |
string |
"subtle" |
Menu accent style: "subtle", "bold" |
registries |
Record<string, string | { url: string, headers?: Record<string, string> }> |
— | Custom registry definitions |
Important
The
registriesfield supports two forms. A simple string is treated as the registry URL. An object form allows specifyingurland optionalheaders(useful for private registries requiring authentication). URLs support{name}and{style}template placeholders.
Example components.json
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york-v4",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "app/globals.css",
"baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide",
"rtl": false,
"registries": {
"acme": "https://components.acme.com/r"
}
}
3.2 Environment Variables
| Variable | Purpose | Where Used |
|---|---|---|
REGISTRY_URL |
Override the default registry base URL (https://ui.shadcn.com/r) |
packages/shadcn/src/registry/constants.ts |
https_proxy |
Route all registry HTTP fetches through a proxy | packages/shadcn/src/registry/fetcher.ts |
SHADCN_TEMPLATE_DIR |
Override the template directory for project scaffolding | packages/shadcn/src/utils/scaffold.test.ts |
SHADCN_GITHUB_URL |
Override the GitHub URL used during scaffolding | packages/shadcn/src/utils/scaffold.test.ts |
npm_config_user_agent |
Read by the CLI to detect which package manager invoked it | packages/shadcn/src/utils/get-package-manager.ts |
Note
The
SHADCN_TEMPLATE_DIRandSHADCN_GITHUB_URLvariables are primarily used in test environments. TheREGISTRY_URLvariable is the recommended way to point the CLI at a custom or self-hosted registry during development or in air-gapped environments.
3.3 Registry URL Configuration in components.json
Registry URLs in the registries field support environment variable expansion using ${VAR} syntax. This allows storing tokens or dynamic segments in environment variables rather than hardcoding them:
{
"registries": {
"private": {
"url": "https://registry.internal.com/r",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}"
}
}
}
}
The builder resolves ${REGISTRY_TOKEN} from process.env at fetch time. If the variable is not set, the CLI raises RegistryMissingEnvironmentVariablesError.
3.4 CLI Commands and Options — Complete Reference
The CLI registers 12 commands in packages/shadcn/src/index.ts. Below is every command with every option, written from the Commander.js definitions in source.
3.4.1 shadcn init
Initialize a new shadcn/ui project or reconfigure an existing one.
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--template |
-t |
string |
— | Project template to use |
--base |
-b |
string |
— | Base UI library (radix or base) |
--monorepo / --no-monorepo |
— | boolean |
— | Enable/disable monorepo mode |
--preset |
-p |
string |
— | Named preset or preset code |
--yes |
-y |
boolean |
false |
Skip confirmation prompts |
--defaults |
-d |
boolean |
false |
Use default configuration |
--force |
-f |
boolean |
false |
Overwrite existing configuration |
--cwd |
-c |
string |
. |
Working directory |
--name |
-n |
string |
— | Project name (for new projects) |
--silent |
-s |
boolean |
false |
Suppress output |
--css-variables / --no-css-variables |
— | boolean |
— | Enable/disable CSS variables |
--rtl / --no-rtl |
— | boolean |
— | Enable/disable RTL mode |
--reinstall / --no-reinstall |
— | boolean |
— | Reinstall dependencies |
3.4.2 shadcn add
Add components to a project from the registry.
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--yes |
-y |
boolean |
false |
Skip confirmation prompts |
--overwrite |
-o |
boolean |
false |
Overwrite existing files |
--all |
-a |
boolean |
false |
Add all available components |
--path |
-p |
string |
— | Custom path for component files |
--silent |
-s |
boolean |
false |
Suppress output |
--dry-run |
— | boolean |
false |
Show what would be added without writing |
--diff |
— | boolean |
false |
Show diff of changes |
--view |
— | boolean |
false |
View component source without adding |
--cwd |
-c |
string |
. |
Working directory |
3.4.3 shadcn apply
Apply a preset to an existing project.
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--preset |
— | string |
— | Preset name or code to apply |
--yes |
-y |
boolean |
false |
Skip confirmation prompts |
--silent |
-s |
boolean |
false |
Suppress output |
--cwd |
-c |
string |
. |
Working directory |
3.4.4 shadcn build
Build a custom component registry from local source.
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--output |
-o |
string |
./public/r |
Output directory for the built registry |
--cwd |
-c |
string |
. |
Working directory |
3.4.5 shadcn diff
Show differences between local components and registry versions.
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--yes |
-y |
boolean |
false |
Skip confirmation prompts |
--cwd |
-c |
string |
. |
Working directory |
Warning
The
diffcommand is deprecated. It remains functional but may be removed in a future release.
3.4.6 shadcn docs
Display documentation for components.
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--json |
— | boolean |
false |
Output as JSON |
--cwd |
-c |
string |
. |
Working directory |
--base |
-b |
string |
— | Base library filter |
3.4.7 shadcn info
Display project configuration information.
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--json |
— | boolean |
false |
Output as JSON |
--cwd |
-c |
string |
. |
Working directory |
3.4.8 shadcn search
Search the component registry.
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--query |
-q |
string |
— | Search query |
--limit |
-l |
number |
— | Maximum results to return |
--offset |
-o |
number |
— | Offset for pagination |
--cwd |
-c |
string |
. |
Working directory |
3.4.9 shadcn migrate
Run migrations (icon library, radix-to-base, RTL, etc.).
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--list |
-l |
boolean |
false |
List available migrations |
--yes |
-y |
boolean |
false |
Skip confirmation prompts |
--cwd |
-c |
string |
. |
Working directory |
3.4.10 shadcn mcp
Start the MCP (Model Context Protocol) server.
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--cwd |
-c |
string |
. |
Working directory |
Subcommand: shadcn mcp init
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--client |
— | string |
— | Target MCP client (claude, cursor, vscode, codex, opencode) |
3.4.11 shadcn view
View component source code from the registry.
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--cwd |
-c |
string |
. |
Working directory |
3.4.12 shadcn registry
Registry management commands.
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--cwd |
-c |
string |
. |
Working directory |
3.5 Workspace Configuration (Monorepo)
In monorepo mode, the CLI detects workspace roots by examining the package manager's workspace configuration (pnpm-workspace.yaml, package.json#workspaces). It then:
- Creates a root-level
components.jsonwith shared settings. - Routes component files to the correct workspace package based on type:
registry:uiitems route to the UI packageregistry:hookitems route to the hooks package- Other items route to the consuming application
- Propagates design settings (
menuColor,menuAccent,rtl,iconLibrary) to workspace-levelcomponents.jsonfiles.
4. Deployment & Scaling
4.1 Building the CLI Package
The CLI is built with tsup (a TypeScript bundler based on esbuild). The build configuration lives in the packages/shadcn/ workspace.
# From monorepo root
pnpm --filter shadcn build
This produces a single ESM bundle at packages/shadcn/dist/index.js with the #!/usr/bin/env node shebang, ready for npm publishing.
4.2 Publishing to npm
The project uses Changesets for version management and publishing:
# Create a changeset
pnpm changeset
# Version packages based on changesets
pnpm changeset version
# Publish to npm
pnpm pub:release # stable release
pnpm pub:beta # beta release
Important
The
releasescript in the rootpackage.jsonorchestrates the full release pipeline via Turbo. Always runpnpm releasefor production releases rather than publishing individual packages manually.
4.3 Building the Documentation Website
The docs site is a Next.js 16 application at apps/v4/:
# Development (with Turbopack)
pnpm v4:dev
# Production build
pnpm v4:build
The dev server runs on port 4000. The site uses Next.js App Router with MDX content powered by Fumadocs.
4.4 Building a Custom Component Registry
Organizations can host their own component registries. The shadcn build command compiles a registry from local source:
# Build registry to default output (./public/r)
npx shadcn build
# Build registry to custom output
npx shadcn build -o ./dist/registry
The built registry is a set of static JSON files that can be served from any HTTP server or CDN. The output structure follows the same format as the official registry at https://ui.shadcn.com/r.
Registry Item Structure
Each registry item is a JSON file containing:
{
"name": "button",
"type": "registry:ui",
"files": [
{
"path": "ui/button.tsx",
"content": "...",
"type": "registry:ui",
"target": "components/ui/button.tsx"
}
],
"dependencies": ["@radix-ui/react-slot"],
"devDependencies": [],
"cssVars": {},
"css": "",
"tailwind": {},
"fonts": [],
"envVars": [],
"docs": ""
}
Registry Item Types
| Type | Description |
|---|---|
registry:ui |
UI component |
registry:theme |
Theme definition |
registry:style |
Style variant |
registry:base |
Base configuration |
registry:font |
Font definition |
registry:hook |
React hook |
registry:lib |
Library utility |
4.5 Deploying the Documentation Site
The Next.js docs site can be deployed to any platform that supports Next.js:
# Build for production
cd apps/v4
pnpm build
# The output is in .next/ — deploy per your hosting platform
Note
The official site at
ui.shadcn.comserves both documentation and the component registry. The registry is built byscripts/build-registry.tsand output topublic/r/within the website.
5. Operations
5.1 Development Environment Setup
# Clone and install
git clone https://github.com/shadcn-ui/ui.git
cd ui
pnpm install
# Start all dev servers in parallel
pnpm dev
# Or start specific workspaces
pnpm v4:dev # Docs website on port 4000
pnpm shadcn:dev # CLI in dev mode
5.2 Building the Component Registry
The registry build is a critical step that compiles all component source files from apps/v4/registry/ into static JSON served by the docs site:
pnpm registry:build
This runs apps/v4/scripts/build-registry.ts, which:
- Reads all component definitions from
apps/v4/registry/. - Resolves dependencies between components.
- Compiles each component into a registry JSON file.
- Writes output to
apps/v4/public/r/.
The registry source is organized into bases:
apps/v4/registry/bases/
├── base/ # Base UI primitives
│ ├── ui/ # Components
│ ├── blocks/ # Page-level compositions
│ └── examples/ # Usage examples
└── radix/ # Radix UI primitives
├── ui/ # Components
├── blocks/ # Page-level compositions
└── examples/ # Usage examples
5.3 Running Tests
# Full test suite (builds registry, starts server, runs vitest)
pnpm test
# Run CLI unit tests only
pnpm --filter shadcn test
# Run integration tests only
pnpm --filter tests test
Warning
The full
pnpm testcommand first builds the registry and starts a local server, then runs all Vitest suites. This can take several minutes. For iterative development, use the filtered commands above.
5.4 Template Syncing
Templates in templates/ serve as scaffolding for shadcn init. They must stay synchronized with the latest component conventions:
pnpm sync:templates
This copies shared configuration and boilerplate across all 10 template variants.
5.5 Registry Capture (Screenshots)
For documentation, the registry capture script generates screenshots of all components:
pnpm registry:capture
5.6 Linting
pnpm lint # Check for linting issues
pnpm lint:fix # Auto-fix where possible
5.7 Monorepo Task Graph
Turborepo manages the task dependency graph. Key tasks defined in turbo.json:
| Task | Dependencies | Outputs |
|---|---|---|
build |
^build (dependent builds first) |
dist/** |
dev |
— (runs in parallel) | — |
lint |
— | — |
test |
build |
— |
6. Performance
6.1 Turbopack for Development
The documentation site (apps/v4/) uses Turbopack as its development bundler via Next.js 16. Turbopack provides near-instant hot module replacement (HMR) for the 8,550+ files in the monorepo, significantly faster than webpack for large codebases.
6.2 Registry Fetch Optimization
The registry fetcher (packages/shadcn/src/registry/fetcher.ts) optimizes network requests through:
- Dependency deduplication: When resolving a component tree, the resolver tracks already-fetched items to avoid duplicate requests.
- Parallel fetching: Independent dependencies are fetched concurrently.
- Proxy support: The
https_proxyenvironment variable routes traffic through a corporate or caching proxy, reducing latency in enterprise environments.
6.3 Component Resolution
The resolver (packages/shadcn/src/registry/resolver.ts) builds a dependency tree for each requested component:
- Fetch the requested item from the registry.
- Extract its
dependencies(npm packages) andregistryDependencies(other registry items). - Recursively resolve all registry dependencies, deduplicating along the way.
- Return a flat list of all items to install, in dependency order.
This ensures that adding a complex component like data-table automatically pulls in all required sub-components (e.g., table, button, dropdown-menu) without duplicating any.
6.4 Build Performance
Turborepo provides:
- Task caching: Build outputs are cached based on file hashes; unchanged packages are not rebuilt.
- Parallel execution: Independent tasks run concurrently across all available CPU cores.
- Incremental builds: Only modified packages and their dependents are rebuilt.
7. Security
7.1 Registry Fetch Security
All registry fetches use HTTPS by default. The default registry URL is https://ui.shadcn.com/r. The fetcher in packages/shadcn/src/registry/fetcher.ts enforces:
- HTTPS transport: The registry URL scheme is not validated at the code level, but the default and all official registries use HTTPS.
- Proxy support: When
https_proxyis set, requests are routed through anhttps-proxy-agent, enabling corporate proxy inspection and logging. - Error classification: The fetcher maps HTTP status codes to specific error classes (
RegistryNotFoundErrorfor 404,RegistryUnauthorizedErrorfor 401,RegistryForbiddenErrorfor 403,RegistryGoneErrorfor 410), providing clear diagnostics.
Caution
Custom registries specified in
components.jsoncan point to any URL. In shared or CI environments, audit theregistriesfield to ensure it references trusted sources only. A compromised registry could inject malicious code into components that the CLI writes directly to your source tree.
7.2 Environment Variable Handling
Registry URLs and headers support ${VAR} expansion from process.env. The CLI raises RegistryMissingEnvironmentVariablesError if a referenced variable is not set, preventing accidental requests with empty authentication tokens.
Caution
Environment variables referenced in
headers(e.g.,Authorization: Bearer ${TOKEN}) are expanded at runtime and sent in HTTP requests. Store sensitive tokens in environment variables rather than hardcoding them incomponents.json, which may be committed to version control.
7.3 Registry Validation
The registry system validates incoming data at multiple levels:
- Schema validation: All registry responses are validated against Zod schemas (
packages/shadcn/src/schema/). Malformed responses are rejected withRegistryParseError. - Namespace validation: Registry namespaces (e.g.,
@shadcn,@v0) are validated against the configured registries. Unknown namespaces raiseRegistryInvalidNamespaceError. - Config validation: The
components.jsonfile is validated on load. Missing or malformed configuration raisesConfigMissingErrororConfigParseError.
7.4 Safe Target Path Validation
When the CLI writes component files to disk, it validates target paths using the isSafeTarget function. This prevents path traversal attacks where a malicious registry item could specify a target like ../../../etc/passwd. The validator ensures:
- Target paths are within the project directory.
- Target paths do not traverse above the project root.
- Target paths do not overwrite critical project files (e.g.,
package.json, config files).
Important
The
isSafeTargetcheck is a critical security boundary. It runs before any file write operation duringshadcn add. If a registry item specifies a target path that fails validation, the entire operation is aborted.
7.5 Credential Hygiene
- Registry authentication tokens belong in environment variables, not in
components.json. - The CLI does not log or display registry headers (which may contain tokens).
- The
--dry-runflag onshadcn addallows previewing what will be written without executing any file operations or network requests beyond the initial fetch.
8. Developer Internals
8.1 Repository Structure
shadcn-ui/ui/
├── apps/
│ └── v4/ # Next.js 16 documentation website
│ ├── app/ # App Router pages and layouts
│ ├── registry/ # Component registry source
│ │ ├── bases/
│ │ │ ├── base/ # Base UI components, blocks, examples
│ │ │ └── radix/ # Radix UI components, blocks, examples
│ │ ├── new-york-v4/ # New York v4 style variant
│ │ ├── icons/ # Icon library definitions
│ │ └── styles/ # Style definitions
│ ├── styles/ # Pre-built CSS style variants
│ ├── content/docs/ # MDX documentation pages
│ ├── examples/ # Live example components
│ ├── lib/ # Shared website utilities (21 files)
│ ├── hooks/ # Website React hooks
│ ├── components/ # Website-specific components
│ └── scripts/ # Build scripts
│ ├── build-registry.ts # Compiles registry JSON
│ ├── build-icons.ts # Compiles icon definitions
│ └── ...
├── packages/
│ ├── shadcn/ # CLI package (npm: "shadcn")
│ │ ├── src/
│ │ │ ├── index.ts # CLI entry point (Commander setup)
│ │ │ ├── commands/ # 12 command implementations
│ │ │ ├── registry/ # Registry system (fetch, resolve, build)
│ │ │ ├── utils/ # Utilities (transforms, updaters, config)
│ │ │ ├── schema/ # Zod validation schemas
│ │ │ ├── preflights/ # Pre-flight check system
│ │ │ ├── preset/ # Preset system
│ │ │ ├── templates/ # Framework template handlers
│ │ │ ├── migrations/ # Migration system
│ │ │ ├── mcp/ # MCP server implementation
│ │ │ ├── icons/ # Icon library definitions
│ │ │ └── styles/ # Style definitions
│ │ └── test/ # CLI unit tests with fixtures
│ └── tests/ # Integration tests
├── templates/ # 10 project scaffolding templates
│ ├── next-app/
│ ├── next-monorepo/
│ ├── vite-app/
│ ├── vite-monorepo/
│ ├── react-router-app/
│ ├── react-router-monorepo/
│ ├── start-app/
│ ├── start-monorepo/
│ ├── astro-app/
│ └── astro-monorepo/
└── skills/
└── shadcn/ # AI agent skill definitions
8.2 CLI Entry Point — packages/shadcn/src/index.ts
The entry point configures Commander.js with all 12 commands. Each command is imported from packages/shadcn/src/commands/ and registered with its options. The file includes the shebang #!/usr/bin/env node for direct execution.
8.3 Command Modules — packages/shadcn/src/commands/
This directory contains 12 files (approximately 90K characters of TypeScript total), one per CLI command.
| File | Command | Description |
|---|---|---|
init.ts |
shadcn init |
Project initialization. Detects framework, runs preflights, applies template, creates components.json, installs base dependencies. Supports preset-based initialization. |
add.ts |
shadcn add |
Component addition. Resolves registry tree, runs transforms, writes files. The most complex command — orchestrates the entire fetch-transform-write pipeline. |
apply.ts |
shadcn apply |
Preset application. Decodes a preset (named or encoded) and applies it to an existing project's components.json and CSS. |
diff.ts |
shadcn diff |
Component diffing. Fetches the latest registry version of installed components and shows a unified diff against local versions. Deprecated. |
docs.ts |
shadcn docs |
Documentation display. Fetches and renders component documentation from the registry. |
view.ts |
shadcn view |
Component viewing. Displays component source code from the registry without writing any files. |
search.ts |
shadcn search |
Registry search. Queries the registry API for components matching a search term. |
migrate.ts |
shadcn migrate |
Migration runner. Executes available migrations (icon library swap, radix-to-base, RTL enablement). |
info.ts |
shadcn info |
Project info. Displays the current components.json configuration and detected project settings. |
build.ts |
shadcn build |
Registry builder. Compiles a custom registry from local source into static JSON. |
mcp.ts |
shadcn mcp |
MCP server. Starts a Model Context Protocol server for AI tool integration. Has init subcommand for client configuration. |
registry.ts |
shadcn registry |
Registry management commands. |
8.4 Registry System — packages/shadcn/src/registry/
The registry system (28 files, approximately 61K characters) handles all interaction with component registries — fetching, resolving dependencies, building custom registries, and validating data.
| File | Role |
|---|---|
api.ts |
High-level registry API functions used by commands |
builder.ts |
Builds custom registries from local source files; supports env var expansion in URLs (${VAR} syntax) and headers |
config.ts |
Registry configuration management, URL resolution, namespace mapping |
constants.ts |
Default registry URL (https://ui.shadcn.com/r), built-in registry definitions (@shadcn, @v0) |
context.ts |
Registry context object carrying config + state through operations |
errors.ts |
15 error classes for granular error handling (see hierarchy below) |
fetcher.ts |
HTTP fetch with https-proxy-agent proxy support, status-to-error mapping, response parsing |
resolver.ts |
Recursive dependency tree resolution with deduplication; produces flat install order |
search.ts |
Registry search implementation for shadcn search command |
validator.ts |
Zod-based validation of registry responses against schema definitions |
utils.ts |
Shared registry utilities (URL construction, name parsing, namespace extraction) |
8.4.1 Error Hierarchy
The registry defines 15 error classes in errors.ts, all extending RegistryError:
RegistryError (base)
├── RegistryNotFoundError (HTTP 404)
├── RegistryGoneError (HTTP 410)
├── RegistryUnauthorizedError (HTTP 401)
├── RegistryForbiddenError (HTTP 403)
├── RegistryFetchError (other HTTP errors)
├── RegistryNotConfiguredError (registry not in components.json)
├── RegistryLocalFileError (local file access issues)
├── RegistryParseError (malformed JSON response)
├── RegistryMissingEnvironmentVariablesError
├── RegistryInvalidNamespaceError
├── ConfigMissingError (no components.json found)
├── ConfigParseError (invalid components.json)
├── RegistriesIndexParseError (invalid registries index response)
└── InvalidConfigIconLibraryError (unknown icon library in config)
8.4.2 Built-in Registries
Two registries are built in and do not need explicit configuration:
| Namespace | URL | Purpose |
|---|---|---|
@shadcn |
https://ui.shadcn.com/r |
Official shadcn/ui component registry |
@v0 |
v0.dev integration URL | Integration with Vercel's v0.dev AI design tool |
Components are referenced by namespace/name syntax. Bare names (no namespace) default to @shadcn.
8.4.3 Registry Resolution Algorithm
When shadcn add button dropdown-menu is invoked, the resolver executes:
- Parse names: Split each argument into namespace + component name. Bare names default to
@shadcn. - Resolve registry URL: Map namespace to URL via
constants.ts(built-in) orcomponents.json#registries(custom). - Fetch root items: HTTP GET each component JSON from
{registryUrl}/styles/{style}/{name}.json. - Extract registry dependencies: Each item may declare
registryDependencies— other registry items it depends on. - Recursive resolution: For each dependency not already seen, repeat steps 2-4. A
Setof visited names prevents cycles and duplicates. - Flatten: Return a deduplicated, topologically-ordered list of all items to install.
- Merge: Aggregate all npm
dependenciesanddevDependenciesacross all resolved items.
8.5 Utilities — packages/shadcn/src/utils/
The utilities directory (35 files, approximately 161K characters) contains the heaviest logic in the CLI. Key modules:
| File | Role |
|---|---|
add-components.ts |
Orchestrates the full component-addition pipeline (resolve, validate, deps, config, files, CSS) |
create-project.ts |
Project scaffolding (clone template, configure, install) |
get-config.ts |
Configuration loading via cosmiconfig with Zod validation |
get-project-info.ts |
Framework detection (Next.js, Vite, Astro, React Router, TanStack Start) |
get-package-manager.ts |
Package manager detection (npm, pnpm, yarn, bun) via npm_config_user_agent and lockfile heuristics |
scaffold.ts |
Template-based project scaffolding |
transformers.ts |
Entry point for the 9-stage transform pipeline |
8.5.1 Transform Pipeline Modules
Located within packages/shadcn/src/utils/, these modules implement the AST-based transforms applied to every component file during shadcn add:
| Transform | Order | Module | Description |
|---|---|---|---|
transformImport |
1 | transform-import.ts |
Rewrites import paths to match project aliases (e.g., @/components/ui to the user's configured alias). Uses ts-morph for AST manipulation. |
transformRsc |
2 | transform-rsc.ts |
Adds or removes "use client" directives based on the rsc config flag. Components that use hooks or browser APIs get the directive; server-safe components do not. |
transformCssVars |
3 | transform-css-vars.ts |
Converts between inline Tailwind utility classes and CSS custom property usage based on tailwind.cssVariables. |
transformTwPrefixes |
4 | transform-tw-prefixes.ts |
Applies Tailwind class prefixes (e.g., bg-primary becomes tw-bg-primary) when tailwind.prefix is set. |
transformIcons |
5 | transform-icons.ts |
Swaps icon imports between icon libraries (e.g., Lucide to custom icon set) based on iconLibrary configuration. |
transformMenu |
6 | transform-menu.ts |
Applies menu color and accent transforms based on menuColor and menuAccent settings. |
transformRtl |
7 | transform-rtl.ts |
Applies right-to-left layout transforms: swaps left/right classes, adjusts margin and padding directional utilities, mirrors layout-related properties. |
transformFont |
8 | transform-font.ts |
Processes font marker comments in component source, replacing them with the configured font family. |
transformCleanup |
9 | transform-cleanup.ts |
Final cleanup pass: removes internal markers, normalizes whitespace, ensures consistent formatting of the output file. |
Note
Transforms use a combination of Babel (for JSX/TSX parsing), ts-morph (for TypeScript AST manipulation), and recast (for code printing that preserves formatting). This three-tool approach handles the full spectrum of code transformations while maintaining readable output.
8.5.2 Updater Modules
These modules handle the "write phase" after transforms complete:
| File | Role |
|---|---|
updaters/update-dependencies.ts |
Runs npm install / pnpm add / yarn add / bun add for newly required npm dependencies |
updaters/update-tailwind-config.ts |
Patches the Tailwind configuration file with new content paths or plugins required by added components |
updaters/update-files.ts |
Writes transformed component files to disk with isSafeTarget validation |
updaters/update-css.ts |
Updates the global CSS file with new CSS variable definitions or component styles (run last to trigger rebuild) |
updaters/update-env-vars.ts |
Adds required environment variables to .env files when components declare envVars |
updaters/update-fonts.ts |
Registers font imports required by components |
8.5.3 Component Addition Orchestration
The add-components.ts module orchestrates the full write phase in a specific order designed for correctness:
- Resolve registry tree — fetch the component and all transitive dependencies.
- Validate file targets — ensure all target paths pass
isSafeTarget. - Update dependencies — install npm packages first so TypeScript/bundler can resolve imports.
- Update Tailwind config — add content paths or plugins.
- Update env vars — write
.enventries. - Update fonts — register font imports.
- Write files — write all transformed component files.
- Update CSS — write CSS changes last to trigger a hot reload that picks up all preceding changes.
Tip
The CSS-last ordering is intentional. In development with HMR, a CSS change triggers a rebuild. By making it the final step, the rebuild sees all new files and dependencies already in place, avoiding transient errors.
8.6 Pre-flight Checks — packages/shadcn/src/preflights/
Pre-flight checks run before command execution to validate the project environment:
| Check | Purpose |
|---|---|
| Framework detection | Verify the project uses a supported framework |
| TypeScript detection | Determine .ts/.tsx vs .js/.jsx output |
| Tailwind CSS detection | Verify Tailwind is configured and locate its CSS entry point |
| Package manager detection | Determine which package manager to use for dependency installation |
| RSC detection | Determine if the project supports React Server Components |
| Config validation | Validate components.json exists and is well-formed |
8.7 Preset System — packages/shadcn/src/preset/
Presets encode a complete design configuration — style, base, font, icon library, colors, menu settings — into either a named preset or a compact encoded string.
Named presets include: lyra, nova, sera, and others. Each preset maps to a specific combination of configuration values that produce a cohesive visual design.
Preset codes are compact strings generated by the preset builder at ui.shadcn.com/create. They encode all configuration as a URL-safe string that the CLI can decode and apply. The encoding captures:
- Style variant
- Base UI library (Radix or Base)
- Font family
- Icon library
- Color palette
- Menu color and accent
- RTL setting
The preset system is used by both shadcn init --preset and shadcn apply --preset.
8.8 Template System — packages/shadcn/src/templates/
Each of the 10 supported framework configurations has a template handler:
| Template | Framework | Layout |
|---|---|---|
next |
Next.js | Single application |
next-monorepo |
Next.js | pnpm workspace monorepo |
vite |
Vite (React) | Single application |
vite-monorepo |
Vite (React) | pnpm workspace monorepo |
react-router |
React Router | Single application |
react-router-monorepo |
React Router | pnpm workspace monorepo |
start |
TanStack Start | Single application |
start-monorepo |
TanStack Start | pnpm workspace monorepo |
astro |
Astro | Single application |
astro-monorepo |
Astro | pnpm workspace monorepo |
Each template handler implements:
init()— framework-specific initialization logic (copy boilerplate, configure package.json, set up routing)postInit()— post-initialization steps (e.g.,git init, install dependencies)
Template source files live in the top-level templates/ directory. Each template directory contains a complete, minimal project scaffold for its framework. The pnpm sync:templates command synchronizes shared files across all templates.
8.9 Migration System — packages/shadcn/src/migrations/
Migrations handle breaking changes between versions and enable bulk transformations across installed components. Available migrations:
| Migration | Purpose |
|---|---|
| Icons migration | Swap between icon libraries across all installed components (e.g., migrating from Lucide to a custom icon set) |
| Radix migration | Migrate components from Radix UI to Base UI primitives (or vice versa), rewriting imports and adapting API usage |
| RTL migration | Enable or disable RTL support across all installed components, applying directional transforms |
Migrations are run via shadcn migrate. The --list flag shows available migrations without executing them. The --yes flag skips confirmation prompts for CI usage.
8.10 MCP Server — packages/shadcn/src/mcp/
The MCP (Model Context Protocol) server exposes shadcn/ui's component-addition capabilities to AI coding tools. It implements the @modelcontextprotocol/sdk server interface, allowing AI agents to programmatically:
- Search the component registry
- Add components to the project
- View component documentation
- Inspect project configuration
Supported clients (configured via shadcn mcp init --client):
| Client | Config File | Format |
|---|---|---|
| Claude Code | .mcp.json |
JSON (project root) |
| Cursor | .cursor/mcp.json |
JSON |
| VS Code | .vscode/mcp.json |
JSON |
| Codex | ~/.codex/config.toml |
TOML |
| OpenCode | opencode.json |
JSON |
The shadcn mcp init command generates the appropriate configuration file for the chosen client, pointing it at the shadcn mcp server command. After initialization, the AI tool can invoke shadcn operations as MCP tool calls.
8.11 Schema Definitions — packages/shadcn/src/schema/
Zod schemas define and validate all data structures at system boundaries:
| Schema | Validates |
|---|---|
| Config schema | components.json structure (all fields, types, constraints) |
| Registry item schema | Individual registry entries (files, dependencies, metadata) |
| Registry index schema | Registry listing responses (array of available items) |
| Preset schema | Preset definitions and encoded preset codes |
Every external input — config files loaded from disk, JSON fetched from registries, user-provided options — passes through Zod validation before use. Parse failures produce structured ZodError instances with path information for debugging.
8.12 Icon Libraries — packages/shadcn/src/icons/
Icon library definitions map icon names to their import sources. The system supports multiple icon libraries, and the iconLibrary config key determines which one is active. The CLI uses these definitions when:
- Initializing a project with a specific icon library via
shadcn init - Migrating between icon libraries via
shadcn migrate - Transforming icon imports during
shadcn add(thetransformIconsstage)
Each icon library definition maps logical icon names (e.g., "chevron-right", "search", "close") to their actual import paths and component names in the target library.
8.13 Style Definitions — packages/shadcn/src/styles/
Style definitions describe the available component style variants. These are referenced by the style field in components.json. The apps/v4/styles/ directory contains pre-built CSS for each style variant:
base-*variants — styles built for Base UI componentsradix-*variants — styles built for Radix UI components
Each style variant determines the default appearance of components: colors, spacing, border radius, typography, and other visual properties.
8.14 Code Patterns and Conventions
ESM throughout: The entire codebase uses ECMAScript modules. The CLI bundle is ESM with a Node.js shebang. All imports use the import statement; there are no CommonJS require() calls.
Zod for validation: Every external data boundary (config files, registry responses, CLI arguments) is validated with Zod schemas. Parsing failures produce structured errors with clear messages and paths.
Commander.js for CLI: All command definitions, option parsing, and help text generation are handled by Commander.js. Each command module exports a function that receives the Commander program instance and registers its options.
cosmiconfig for config loading: The components.json file is loaded via cosmiconfig, which searches for configuration in multiple formats and locations. The search resolves the nearest config file up the directory tree.
Atomic write ordering: File writes during shadcn add follow a strict order (dependencies first, CSS last) to ensure consistent project state at every intermediate step.
Error-first design: The registry system uses a rich error hierarchy (15 classes) to provide specific, actionable error messages. HTTP errors are mapped to domain-specific error types that carry context about what went wrong and how to fix it.
ts-morph for AST transforms: TypeScript source files are manipulated programmatically using ts-morph (v26.0), which wraps the TypeScript compiler API in a developer-friendly interface. Babel handles JSX parsing, and recast preserves original formatting when printing modified ASTs.
8.15 Testing Strategy
Unit Tests — packages/shadcn/test/
The CLI unit tests use Vitest with an extensive fixture system:
| Fixture Category | Configurations Tested |
|---|---|
| Next.js | App Router, Pages Router, /src layout, monorepo |
| Vite | Standard, monorepo |
| Remix | Standard layout |
| T3 Stack | Standard layout |
| Custom aliases | Various alias configurations |
Tests cover:
- Config loading and validation
- Project detection across all supported frameworks
- Package manager detection from multiple signals
- Transform pipeline correctness (import rewriting, RSC directive handling, CSS variable conversion, Tailwind prefix application, icon swapping, menu transforms, RTL transforms, font processing, cleanup)
- Registry fetching and parsing (mocked with MSW)
- Preset encoding and decoding
- Scaffold and template system
Integration Tests — packages/tests/
Integration tests exercise the full pipeline end-to-end:
- Build the component registry from source (
pnpm registry:build). - Start a local HTTP server to serve the built registry.
- Run CLI commands against the local registry.
- Verify output files match expectations (correct imports, correct file locations, correct dependencies).
Mock Service Worker (MSW)
Registry API calls in unit tests are intercepted by MSW handlers that return fixture data. This avoids network dependency in tests while exercising the full fetch-parse-validate pipeline. MSW handlers are configured to return realistic registry responses matching the production schema.
8.16 Potential Improvements
Based on source analysis, these areas present opportunities for enhancement:
| Area | Observation |
|---|---|
| Transactional writes | When a multi-component add fails partway through, already-written files are not rolled back. A transactional write approach (write to temp, then atomically move) would improve reliability. |
| Local registry cache | The CLI fetches registry data on every invocation. A local cache with TTL-based invalidation would reduce network calls, improve offline support, and speed up repeated operations. |
| Single-pass transforms | The 9-stage transform pipeline parses and re-prints the AST multiple times. A single-pass approach with composed visitors would reduce parse overhead for large component files. |
| Broader workspace detection | Monorepo detection relies on pnpm, npm, yarn, and bun workspace patterns. Nx and Lerna workspaces are not currently detected. |
| Config migration | When the components.json schema changes between CLI versions, users must manually update their configuration. An automatic config migration system (similar to the component migration system) would smooth upgrades. |
| Offline mode | No explicit offline mode exists. The CLI could fall back to a local cache or bundled registry subset when network is unavailable. |
8.17 Contributing
Development Workflow
- Fork and clone the repository.
- Install dependencies:
pnpm install - Create a feature branch.
- Make changes.
- Run tests:
pnpm test - Run linting:
pnpm lint - Create a changeset:
pnpm changeset(for changes that affect published packages). - Submit a pull request.
Key Development Commands
| Command | Purpose |
|---|---|
pnpm dev |
Start all dev servers in parallel |
pnpm shadcn:dev |
Run CLI in dev mode (watches for changes) |
pnpm shadcn:prod |
Run CLI against production registry |
pnpm registry:build |
Rebuild component registry from source |
pnpm registry:capture |
Capture component screenshots for docs |
pnpm test |
Full test suite (build + serve + vitest) |
pnpm lint |
ESLint checks across all packages |
pnpm lint:fix |
Auto-fix lint issues |
pnpm sync:templates |
Synchronize template scaffolds |
pnpm v4:dev |
Run docs website in dev mode (port 4000) |
pnpm v4:build |
Production build of docs website |
Adding a New Component to the Registry
- Create the component source in
apps/v4/registry/bases/{base}/ui/(chooseradixorbasedirectory). - Define the component's registry metadata (name, type, dependencies, registryDependencies).
- Create usage examples in
apps/v4/registry/bases/{base}/examples/. - Add MDX documentation in
apps/v4/content/docs/. - Run
pnpm registry:buildto compile the registry. - Test locally with
pnpm shadcn:dev add {component-name}. - Add unit tests in
packages/shadcn/test/if the component introduces new patterns.
Adding a New CLI Command
- Create a new file in
packages/shadcn/src/commands/following the existing command pattern. - Export the command registration function.
- Import and register the command in
packages/shadcn/src/index.ts. - Add tests in
packages/shadcn/test/. - Update the
shadcn --helptext if needed (Commander generates it automatically from option definitions).
9. Integration Points
9.1 MCP Protocol Integration
The MCP server (packages/shadcn/src/mcp/) implements the Model Context Protocol, enabling AI coding assistants to interact with shadcn/ui programmatically. The integration is bidirectional:
- AI to shadcn: AI agents invoke CLI operations (add, search, docs) through MCP tool calls.
- shadcn to AI: The
shadcn mcp initcommand configures the appropriate MCP config file for each supported client.
Configuration files written by shadcn mcp init:
| Client | File | Format |
|---|---|---|
| Claude Code | .mcp.json |
JSON (project root) |
| Cursor | .cursor/mcp.json |
JSON |
| VS Code | .vscode/mcp.json |
JSON |
| Codex | ~/.codex/config.toml |
TOML |
| OpenCode | opencode.json |
JSON |
Tip
When using Claude Code with shadcn/ui, run
npx shadcn mcp init --client claudein your project root. This creates.mcp.jsonso Claude can add components directly during conversation.
9.2 Custom Registry API Contract
To host a custom component registry, serve static JSON files at a URL that matches this contract:
Base URL: https://your-registry.com/r
Endpoints (static JSON files):
| Path | Returns |
|---|---|
/r/index.json |
Array of all available registry items with name, type, and description |
/r/styles/{style}/{name}.json |
Individual component definition with files, dependencies, and metadata |
Each component JSON follows the registry item schema:
{
"name": "string",
"type": "registry:ui | registry:hook | registry:lib | ...",
"files": [
{
"path": "string (source path within registry)",
"content": "string (full file content)",
"type": "string (registry item type)",
"target": "string (target path in user's project)"
}
],
"dependencies": ["string (npm package names)"],
"devDependencies": ["string (npm dev package names)"],
"registryDependencies": ["string (other registry item names)"],
"cssVars": {
"light": { "variable-name": "value" },
"dark": { "variable-name": "value" }
},
"css": "string (additional CSS to inject)",
"tailwind": {
"config": {}
},
"fonts": ["string (font definitions)"],
"envVars": ["string (required environment variables)"],
"docs": "string (component documentation markdown)"
}
Tip
Use
shadcn buildto generate a compatible registry from your component source. This ensures the output matches the expected schema without manual JSON authoring.
9.3 v0.dev Integration
The @v0 built-in registry namespace connects to Vercel's v0.dev AI design tool. Components generated by v0 can be added to a shadcn/ui project using:
npx shadcn add @v0/component-id
This fetches the v0-generated component through the @v0 registry, applies the same transform pipeline as standard components (import rewriting, RSC handling, CSS variables, etc.), and writes the result to the project. The integration allows designers to generate components with v0's AI and immediately integrate them into a shadcn/ui project.
9.4 Framework Detection System
The framework detection system (packages/shadcn/src/utils/get-project-info.ts) examines multiple signals to identify the active framework:
| Signal | Frameworks Detected |
|---|---|
package.json dependencies |
Next.js (next), Vite (vite), Astro (astro), React Router (react-router), TanStack Start (@tanstack/start) |
| Config files | next.config.*, vite.config.*, astro.config.*, router config files |
| Directory structure | app/ (App Router), pages/ (Pages Router), src/ layout variants |
| TypeScript config | tsconfig.json paths, compiler options, JSX settings |
The detection result drives:
- Template selection during
shadcn init(which scaffolding to use) - RSC support detection (Next.js App Router = RSC enabled; Vite = no RSC)
- File target resolution (where components are written relative to project root)
- Import alias detection (read from
tsconfig.jsonpaths)
9.5 Package Manager Detection
The package manager detection system (packages/shadcn/src/utils/get-package-manager.ts) uses a multi-signal approach:
| Signal | Priority | Detection |
|---|---|---|
npm_config_user_agent |
Highest | Set automatically by npm/pnpm/yarn/bun when running scripts |
| Lock files | High | pnpm-lock.yaml, package-lock.json, yarn.lock, bun.lockb |
packageManager field |
Medium | package.json#packageManager (Corepack) |
The detected package manager determines:
- Which install command to run (
npm install,pnpm add,yarn add,bun add) - Which workspace configuration format to read
- How to detect monorepo workspace roots
Note
If the CLI detects the wrong package manager, ensure the correct lock file exists in your project root, or invoke the CLI through the correct package manager (e.g.,
pnpm dlx shadcninstead ofnpx shadcn).
9.6 Known Open Issues
The following issues are tracked in the shadcn-ui/ui GitHub repository:
Bugs: #10415, #10414, #4516, #5263, #10411, #9301, #7129, #10377, #6536, #10104, #7202, #7206
Feature Requests: #7187, #7199, #9407
Note
Issue numbers reference the
shadcn-ui/uiGitHub repository. Check the repository's issue tracker for current status, as issues may have been resolved since this document was generated.