new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

shadcn/ui · all subjects

blocks/registry

330 notes in this subject, read out of this brain and free to use. This is page 1 of 6.

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.

Give your agent this brain