Adding a new block category
To add a new category, add an entry to the registryCategories array in apps/www/registry/registry-categories.ts. Each category entry must have: name (display name), slug (URL-friendly identifier), and hidden (boolean to control visibility).
Block page file placement
If a block includes a page file, it must be the first entry in the files array and must have a target property that specifies where the CLI should place the file for file-based routing (e.g., 'app/dashboard/page.tsx').
Block registry definition required properties
A block definition in registry-blocks.ts must include: name (string), author (string with URL), title (string), description (string), type (should be 'registry:block'), registryDependencies (array of component names like 'input', 'button', 'card'), dependencies (array of npm package names like 'zod'), files (array of file objects), and categories (array of category slugs). The schema reference is at https://ui.shadcn.com/schema/registry-item.json.
Block file entry structure
Each file in a block definition's files array must have: path (string path relative to registry root), type (one of 'registry:page', 'registry:component', 'registry:hook', 'registry:lib'), and optionally target (used for page files to specify where CLI should place the file, e.g., 'app/dashboard/page.tsx').
Adding components from community registries
Community registries are built into the shadcn CLI with no additional configuration required. To add a component from a community registry, run: npx shadcn add @<registry>/<component>.
Community registries security notice
Community registries are maintained by third-party developers. Always review code on installation to ensure it meets your security and quality standards.
Install from namespaced registries
Once registries are configured in components.json, you can install resources using namespace syntax: npx shadcn@latest add @v0/dashboard, npx shadcn@latest add @private/button, or install multiple resources with npx shadcn@latest add @acme/header @internal/auth-utils
registries basic URL template configuration
Basic registry configuration uses URL templates with a {name} placeholder that is replaced with the resource name when installing. Example: { '@v0': 'https://v0.dev/chat/b/{name}', '@acme': 'https://registry.acme.com/{name}.json' }
registries configuration
The registries property allows you to configure multiple resource registries for your project. This enables installation of components, libraries, utilities, and other resources from various sources including private registries. Registries can be configured with simple URL templates or advanced configurations with authentication headers and parameters.
registries advanced authentication configuration
Advanced registry configuration supports authentication through headers and custom parameters. Environment variables in the format ${VAR_NAME} are automatically expanded from your environment. Example: { '@private': { 'url': 'https://api.company.com/registry/{name}.json', 'headers': { 'Authorization': 'Bearer ${REGISTRY_TOKEN}', 'X-API-Key': '${API_KEY}' }, 'params': { 'version': 'latest' } } }
Supported registry types
The shadcn MCP server works with any shadcn-compatible registry, including the default shadcn/ui registry, third-party registries following the shadcn registry specification, private company internal component libraries, and namespaced registries with @namespace syntax.
MCP example registries configuration
Example registry configuration in components.json: @acme maps to https://registry.acme.com/{name}.json, and @internal maps to an object with url https://internal.company.com/{name}.json and headers containing Authorization: Bearer ${REGISTRY_TOKEN}
Private registry authentication with environment variables
For private registries requiring authentication, set environment variables in .env.local file. Common variables include REGISTRY_TOKEN and API_KEY, which can be referenced in components.json registry headers using ${VARIABLE_NAME} syntax.
MCP server capabilities overview
The MCP server provides four main capabilities: browsing all available components, blocks, and templates from configured registries; searching for specific components by name or functionality across multiple sources; installing components using natural language prompts; and supporting multiple registries including public, private, and third-party sources.
MCP troubleshooting for 'No tools or prompts' message
If seeing 'No tools or prompts' message: run npx clear-npx-cache to clear the cache, try re-enabling the MCP server in your MCP client, and check logs in Cursor under View -> Output by selecting MCP: project-* in the dropdown.
VS Code MCP configuration file structure
VS Code MCP configuration is added to .vscode/mcp.json file with a servers object containing a shadcn server entry. The shadcn entry specifies command as 'npx' and args as ['shadcn@latest', 'mcp'].
Registries configured in components.json
Registries are configured in the project's components.json file. The configuration uses a registries object where keys are namespace identifiers and values are registry URLs or objects with url and headers properties.
Cursor MCP configuration file structure
Cursor MCP configuration is added to .cursor/mcp.json file with an mcpServers object containing a shadcn server entry. The shadcn entry specifies command as 'npx' and args as ['shadcn@latest', 'mcp'].
Codex MCP configuration file structure
Codex MCP configuration is added manually to ~/.codex/config.toml file. The configuration includes a [mcp_servers.shadcn] section with command set to 'npx' and args set to ['shadcn@latest', 'mcp']. The shadcn CLI cannot automatically update this file.
Registry configuration with authentication headers
Registries can be configured with authentication headers in components.json. A registry entry can be an object with a url property and a headers object containing authentication details such as Authorization bearers that reference environment variables.
Claude Code MCP configuration file structure
Claude Code MCP configuration is added to .mcp.json file in the project root with an mcpServers object containing a shadcn server entry. The shadcn entry specifies command as 'npx' and args as ['shadcn@latest', 'mcp'].
MCP server purpose and capabilities
The shadcn MCP Server allows AI assistants to interact with items from registries. It enables browsing available components, searching for specific ones, and installing them directly into projects using natural language. The MCP server acts as a bridge between AI assistants, component registries, and the shadcn CLI.
Claude Code /mcp debug command
In Claude Code, the /mcp command can be used to debug the MCP server and view its status.
MCP troubleshooting for installation failures
If components fail to install: ensure a valid components.json file exists in the project, confirm target directories exist, ensure write permissions for component directories, and verify that required dependencies are installed.
MCP troubleshooting for registry access issues
If components aren't loading from registries: verify registry URLs are correct in components.json, ensure environment variables are set for private registries, confirm the registry is online and accessible, and verify namespace syntax is correct using @namespace/component format.
MCP troubleshooting steps for unresponsive server
If the MCP server isn't responding: verify MCP server is configured and enabled in the client, restart the MCP client after configuration changes, ensure shadcn is installed in the project, and confirm network access to configured registries.
No configuration needed for shadcn/ui registry
The standard shadcn/ui registry requires no configuration in components.json to be accessible through the MCP server.
Install components from community registries
You can install components from community registries using the CLI with the command 'npx shadcn@latest add @[registry]/[name]', where [registry] is the registry name and [name] is the component name. Available registries can be browsed in the Registry Directory.
React 19 support status table for dependencies
Dependency React 19 support status: radix-ui ✅, lucide-react ✅, class-variance-authority ✅, tailwindcss-animate ✅, embla-carousel-react ✅, recharts ✅, react-hook-form ✅, react-resizable-panels ✅, sonner ✅, react-day-picker ✅, input-otp ✅, vaul ✅, @radix-ui/react-icons ✅, cmdk ✅. All marked with ✅ work with React 19 using npm, pnpm, and bun.
Skill provides registry authoring knowledge
The skill includes guidance on how to build and publish custom component registries: registry.json format, item types, file objects, dependencies, CSS variables, building, hosting, and user configuration.
Formisch insert function for arrays
Use the insert function to add new items to an array field. Pass the form store and a config object with path (array field path) and initialInput (initial values for the new item). By default new items are appended to the end. Use the at property in config to insert at a specific index.
Formisch remove function for arrays
Use the remove function with an at index property in the config to remove items from an array field. Pass the form store and a config object with path (array field path) and at (index of item to remove).
Formisch FieldArray component
Use the FieldArray component from Formisch for managing dynamic array fields. It follows the render-prop pattern like Field. The items array in the render function contains stable keys per item that should be used as React keys.
Formisch reset function usage
Use the top-level reset function from Formisch to reset a form to its initial input. Pass the form store as the first parameter. Optionally pass a config object as the second parameter with initialInput to reset to new values, or keepInput: true to sync the baseline to new data while keeping the user's current edits.
Formisch Switch field pattern
For switches, read field.input and call field.onChange from Switch's onCheckedChange prop. Add aria-invalid prop to the Switch component and data-invalid prop to the Field component to show errors.
Formisch RadioGroup field pattern
For radio groups, read field.input and call field.onChange from RadioGroup's onValueChange prop. Add aria-invalid prop to the RadioGroupItem component and data-invalid prop to the Field component to show errors.
Formisch Checkbox array field pattern
For checkbox arrays, read field.input and update it from onCheckedChange using field.onChange. Include logic to add or remove IDs from the array based on checked state. Add aria-invalid prop to the Checkbox component and data-invalid prop to the Field component. Add data-slot='checkbox-group' to the FieldGroup component for proper styling and spacing.
Formisch Select field pattern
For select components, read field.input and call field.onChange from Select's onValueChange prop. Add aria-invalid prop to the SelectTrigger component and data-invalid prop to the Field component to show errors.
Formisch Textarea field pattern
For textarea fields, spread field.props and provide value={field.input}. Add aria-invalid prop to the Textarea component and data-invalid prop to the Field component to show errors.
Formisch error display pattern
Display errors next to fields using FieldError component. Formisch returns errors as an array of strings, so map them to the shape FieldError expects: errors.map((message) => ({ message })). Add the data-invalid prop to the Field component and aria-invalid prop to form controls like Input, SelectTrigger, Checkbox for styling and accessibility.
Formisch field binding for component-library inputs
For component-library inputs like Radix-based Select, Checkbox, RadioGroup, and Switch, read the value from field.input and call field.onChange(value) to update it.
Formisch field binding for native HTML elements
For native HTML elements like Input and Textarea, spread field.props and provide value={field.input}. Formisch wires up name, ref, onChange, onBlur, and onFocus for you.
Formisch validation modes
Formisch separates the first validation from subsequent validations using the validate and revalidate options on useForm. Validate options: 'submit' (on form submission, default), 'blur' (when field loses focus), 'input' (on every input change), 'initial' (immediately on form creation). Revalidate options: 'input' (on every input change after first run, default), 'blur' (on blur after first run), 'submit' (only on form submission).
Formisch Form component behavior
The Form component from Formisch wraps a native form element. It calls event.preventDefault(), runs validation, and only invokes onSubmit when the data is valid. The output passed to onSubmit is fully typed from the schema.
Formisch useForm hook setup
Create a form instance with the useForm hook from Formisch by passing a schema directly to the hook. The schema is the single source of truth for both runtime validation and static types. No resolver step is needed. Configuration accepts: schema (required, the Valibot schema), initialInput (the initial field values), validate (first validation mode), and revalidate (subsequent validation mode).
Formisch Input field pattern
For input fields, spread field.props and provide value={field.input}. Add aria-invalid prop to the Input component and data-invalid prop to the Field component to show errors.
Formisch Field component naming
Formisch ships its own Field component that can clash with the shadcn Field component. To avoid conflicts, import the Formisch Field as FormischField and keep the shadcn Field under its original name. Either side can be aliased but consistency is required.
Formisch form methods import
Formisch exposes form operations as top-level functions that must be imported individually: getInput, insert, reset, submit, setInput, setErrors, validate, focus, remove, move, swap, replace. Every method follows the same signature where the first parameter is always the form store and the second parameter (if necessary) is always a config object.
Formisch array reordering functions
Formisch exposes move, swap, and replace functions for reordering and replacing array items. They all follow the same (form, config) signature as other Formisch methods.
Formisch array field structure
Wrap array fields in a FieldSet with a FieldLegend and FieldDescription. Inside include a FieldGroup where array items render.
components.json with package.json imports aliases
If using package.json#imports, configure components.json aliases as: components: "#components", utils: "#lib/utils", ui: "#components/ui", lib: "#lib", hooks: "#hooks".
components.json configuration file
Create a components.json file in the project root with schema: https://ui.shadcn.com/schema.json, style: "base-nova", rsc: false, tsx: true, tailwind config with css pointing to src/styles/globals.css, baseColor "neutral", cssVariables true, prefix empty string, aliases for components (@/components), utils (@/lib/utils), ui (@/components/ui), lib (@/lib), hooks (@/hooks), and iconLibrary "lucide".
TanStack Start Card component example
import { createFileRoute } from "@tanstack/react-router"
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card"
export const Route = createFileRoute("/")({ component: App })
function App() {
return (
<Card className="max-w-sm">
<CardHeader>
<CardTitle>Project Overview</CardTitle>
<CardDescription>
Track progress and recent activity for your TanStack Start app.
</CardDescription>
</CardHeader>
<CardContent>
Your design system is ready. Start building your next component.
</CardContent>
</Card>
)
}
Card component import in TanStack Start
The Card component can be imported from @/components/ui/card and includes subcomponents: Card, CardContent, CardDescription, CardHeader, and CardTitle. In a monorepo, import from @workspace/ui/components/card instead.
TanStack Start Button component example
import { createFileRoute } from "@tanstack/react-router"
import { Button } from "@/components/ui/button"
export const Route = createFileRoute("/")({ component: App })
function App() {
return (
<div className="flex min-h-svh items-center justify-center p-6">
<Button>Click me</Button>
</div>
)
}
shadcn/registry import path
Registry functions are available under the subpath import `shadcn/registry`. Example: `import { getRegistryItems } from "shadcn/registry"`.
config option for registry functions
Most registry API functions accept an optional `config` parameter of type `Partial<Config>` with default value of built-in registries only. The config's `registries` field maps a namespace (e.g. `@acme`) to a URL and any authentication headers or environment variables required to reach it.
shadcn/schema import path
Zod schemas for validation are available under the subpath import `shadcn/schema`. Example: `import { registryItemSchema } from "shadcn/schema"`.
CLI commands are not part of public API
The CLI commands themselves are not part of the public API. Only the imports documented in the API reference are considered stable.
useCache option for registry functions
Registry functions accept an optional `useCache` boolean parameter (default: `true`). Registry responses are cached in memory for the lifetime of the process, keyed by resolved URL. Concurrent requests for the same URL are de-duplicated into a single fetch. Set to `false` in long-running processes (servers, watchers, MCP server) where the registry can change between requests and fresh data is needed each time.