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 3 of 6.

Dynamic search example response

Example registry.json response with pagination: ```json { "name": "acme", "homepage": "https://acme.com", "items": [ { "name": "button", "type": "registry:ui", "description": "A button component." }, { "name": "icon-button", "type": "registry:ui", "description": "A button component with an icon." } ], "pagination": { "total": 12, "offset": 0, "limit": 2, "hasMore": true } } ```

Dynamic search testing

Test your dynamic registry with curl: curl "https://acme.com/r/registry.json?q=button&limit=10". Then verify with the CLI: npx shadcn@latest search @acme --query button. To confirm server-side search is active, check that the response includes the pagination object and only the matching items.

Dynamic search backwards compatibility

Static registries require no changes; query parameters on a static file are ignored by the file server and the CLI falls back to local filtering. Older CLI versions fetch the catalog without query parameters and ignore the pagination field; your registry should return a sensible default response for requests without parameters, such as the first page of items. Ranking is up to your server; when your registry returns pre-filtered results, the CLI preserves your order instead of re-ranking locally.

Dynamic search with authentication

Dynamic search works with all authentication patterns. The CLI sends the configured headers and params with the search request, so you can scope search results to the authenticated user. Example: extract the authorization token from request headers and use it to filter items for the authenticated team.

Dynamic search with multiple registries

When searching multiple registries at once, a global offset cannot be split across registries. The CLI forwards q and type to each registry along with a limit large enough to fill the requested page (offset + limit), then merges and paginates the combined results locally. Server-side filtering still applies, so each registry only returns matching items. If your registry caps the number of items per response below the requested limit, the CLI treats it as exhausted for deeper pages. Honor the requested limit where possible so all your matches stay reachable through paging.

Dynamic search Next.js implementation example

Example server implementation using a Next.js route handler: ```typescript import { NextRequest, NextResponse } from "next/server" export async function GET(request: NextRequest) { const { searchParams } = request.nextUrl const query = searchParams.get("q") const types = searchParams.get("type")?.split(",") const limit = Number(searchParams.get("limit") ?? 100) const offset = Number(searchParams.get("offset") ?? 0) // Filter items using your database or search index. const { items, total } = await searchItems({ query, types, limit, offset }) return NextResponse.json({ name: "acme", homepage: "https://acme.com", items, pagination: { total, offset, limit, hasMore: offset + limit < total, }, }) } ``` You can back searchItems with anything: a database query, a full-text search index or an external search service.

Dynamic search overview

By default, shadcn search fetches the entire registry.json and filters items locally. For large registries with thousands of items, you can implement search on the registry server instead. Dynamic search is opt-in and fully backwards compatible. Static registries continue working without any changes.

Dynamic search how it works

When running shadcn search, the CLI appends search parameters to the catalog request. Static registries ignore query parameters and return the full registry.json, with the CLI filtering locally. Dynamic registries filter items server-side and return matching items along with a pagination object. When the CLI sees pagination in the response, it trusts the results as pre-filtered and skips local filtering. The presence of pagination in the response is what tells the CLI your registry handles search server-side. There is no configuration or capability negotiation required.

Complex component registry item structure

A complex registry item can include a page, multiple components, hooks, utility libraries, and config files. Each file is listed in the 'files' array with its path, type, and optional target location. File types include 'registry:page', 'registry:component', 'registry:hook', 'registry:lib', and 'registry:file'.

GitHub repository registry dependencies

To reference a registry item from a GitHub repository, use the full GitHub item address format: 'github-username/repo-name/item-name'. For example, 'acme/ui/button' references the button item from the acme/ui repository.

Pinning GitHub registry items with refs

GitHub registry items can be pinned to a specific version by adding '#ref' to the item address. The ref can be a branch name, tag, or full commit SHA. Example: 'npx shadcn@latest add acme/ui/button#v1.2.0'. For published registries, tags or full commit SHAs are preferred over branches.

GitHub registry addresses only support public repositories

GitHub registry addresses currently support only public github.com repositories. Private repository dependencies are not supported. For private registries, use a namespace with authenticated URLs instead.

Overriding Tailwind theme variables via cssVars

To add or override Tailwind theme variables, add them to the 'cssVars.theme' object. This allows customization of theme properties like sizing, easing, and fonts. For example, 'text-base' can be set to '3rem', 'ease-in-out' to 'cubic-bezier(0.4, 0, 0.2, 1)', and 'font-heading' to 'Poppins, sans-serif'.

Adding custom Tailwind colors via cssVars

To add custom Tailwind colors, define them in the 'cssVars' object under 'light' and 'dark' keys. Colors use oklch color notation. The CLI will update the project CSS file automatically. Custom colors become available as utility classes, for example a 'brand-background' color becomes usable as 'bg-brand' and a 'brand-accent' color becomes 'text-brand-accent'.

Registry page file type with target

A registry item file with type 'registry:page' must include a 'target' property specifying where the page should be installed, for example 'app/hello/page.tsx'.

Registry item schema URL

Registry items must reference the JSON schema at https://ui.shadcn.com/schema/registry-item.json

Bare registry dependency names resolve to shadcn built-ins

Bare dependency names in 'registryDependencies' refer to the built-in shadcn items. For example, 'button' means the official shadcn button component, not a custom version from another registry.

Testing registry with view command

View a specific registry item with: npx shadcn@latest view http://localhost:3000/r/button.json

Namespaced registry view command

View a namespaced registry item with: npx shadcn@latest view @acme/button

Namespaced registry add command

Install from a namespaced registry with: npx shadcn@latest add @acme/button

registry.json required fields

A registry.json file requires the following fields: $schema (set to "https://ui.shadcn.com/schema/registry.json"), name (string identifier for the registry), homepage (URL to the registry), and items (array of registry item definitions). When using the include pattern, only the root registry.json must define name and homepage.

registry.json: entry point for a registry

The registry.json file is the entry point for any registry. It contains the registry's name, homepage, and defines all items present in the registry. It must be present at the root of the registry endpoint. It must conform to the registry schema specification.

Namespaced registry list command

List items in a namespaced registry with: npx shadcn@latest list @acme

Registry item definition required fields

Each item in the registry.json items array requires: name (unique identifier), type (such as registry:ui, registry:block, registry:hook), title (human-readable name), description (what the item does), and files (array with path and type for each file).

Single registry.json vs include pattern

A registry can be structured in two ways: (1) Single registry.json with all items defined in the items array at the root. (2) Using include to compose multiple registry.json files, with a root registry.json that includes nested registry files via the include array. The include pattern is recommended for larger registries.

File paths in include pattern are relative to registry.json location

When using the include pattern, file paths specified in the files array of each item are relative to the registry.json file that declares the item, not the root of the project.

File paths in single registry pattern are relative to project root

In a single registry.json at the root of the project, file paths specified in the files array are relative to the root of the project.

Registry item type field values

Registry item type can be: registry:ui (for UI components), registry:block (for block components), registry:hook (for hooks), registry:component (for components), or other registry types.

registry.json can exist in GitHub repositories

An existing public GitHub repository can be turned into a registry by adding a registry.json file at the root.

Registry framework requirements

A registry can be built with any framework (Next.js, Vite, Vue, Svelte, PHP, etc.) as long as it supports serving JSON over HTTP. It can also be a public GitHub repository with a registry.json file at the root.

shadcn build command generates static registry JSON

Running npx shadcn@latest build generates static registry JSON files. If the source registry uses include, shadcn build resolves the included registries and writes a flattened registry to the output directory. By default, files are generated in public/r, with items available at public/r/[NAME].json. The output directory can be changed with the --output option.

Dynamic registry serving with loadRegistry

Use loadRegistry from shadcn/registry to serve the registry catalog at request time. This function can be used in a route handler like app/r/registry.json/route.ts to return the registry JSON dynamically without needing to run shadcn build.

Dynamic registry serving with loadRegistryItem

Use loadRegistryItem from shadcn/registry to serve individual registry items. It can be used in a route handler like app/r/[name].json/route.ts to return specific item JSON. It throws RegistryItemNotFoundError if an item is not found.

loadRegistry and loadRegistryItem resolve include automatically

Both loadRegistry and loadRegistryItem resolve include before returning JSON, so route handlers can use the same source registry.json structure without running shadcn build.

HTTP Content Negotiation for registry hosting

The shadcn CLI supports HTTP Content Negotiation. From a single URL, you can serve HTML to browsers, JSON to the shadcn CLI, and Markdown to AI agents. The client signals its preference using the Accept request header. The CLI sends User-Agent: shadcn and Accept: application/vnd.shadcn.v1+json, application/json;q=0.9 headers.

Content negotiation with Next.js rewrites

In Next.js, implement content negotiation by setting up rewrites in next.config.ts. Check the Accept header for the value application/vnd\\.shadcn\\.v1\\+json or the User-Agent header for shadcn, and route those requests to your registry JSON. Also set the Vary header to Accept and User-Agent to ensure proper caching.

Content negotiation with Express.js

In Express.js, check req.accepts('application/vnd.shadcn.v1+json') or req.get('User-Agent') === 'shadcn' to detect CLI requests and return registry JSON. For other requests, serve your documentation or homepage. Use res.vary() to set the Vary header for Accept and User-Agent.

Root domain registry hosting benefits

By implementing content negotiation, you can host your registry at your domain root (https://example.com) instead of a sub-path. This enables shorter, branded registry URLs like shadcn add https://ui.example.com, provides easier mnemonics for users, and reduces the need to remember /r/ or /registry/ sub-paths.

Testing registry with list command

Test that a registry catalog can be discovered by running: npx shadcn@latest list http://localhost:3000/r/registry.json

Testing registry with search command

Search a registry by query with: npx shadcn@latest search http://localhost:3000/r/registry.json --query button

Namespaced registry search command

Search a namespaced registry with: npx shadcn@latest search @acme --query button

Testing registry with add command

Test the install flow from a project by running: npx shadcn@latest add http://localhost:3000/r/button.json

Namespaced registry testing with registry add

Add a registry with a namespace using: npx shadcn@latest registry add @acme=http://localhost:3000/r/{name}.json. The {name} placeholder resolves to item JSON files, so @acme/button resolves to http://localhost:3000/r/button.json.

Publishing registry with namespace setup

To make a registry available with a namespace, publish the project to a public URL and tell users to add the registry URL template. The template format is https://acme.com/r/{name}.json, where {name} is replaced with the item name. Users add it with: npx shadcn@latest registry add @acme=https://acme.com/r/{name}.json

Manual namespace registration in components.json

Users can manually add a registry namespace to their components.json file under the registries field. Format: {"registries": {"@acme": "https://acme.com/r/{name}.json"}}

Registry index submission for open source registries

Open source and publicly available registries can be submitted to the official registry index. This allows users to add a namespace by name instead of pasting the full URL template.

Registry item directory structure guideline

Place registry items in the registry/[STYLE]/[NAME] directory, where STYLE can be anything like 'default'. The item should be nested under the registry directory.

Block registry required properties

For blocks, the following properties are required in the registry item definition: name, description, type, and files.

Registry item naming and description recommendation

It is recommended to add a proper name and description to registry items. This helps LLMs understand the component and its purpose.

registryDependencies field for registry item dependencies

List all registry dependencies in the registryDependencies field of a registry item. A registry dependency is an item address such as button, @acme/input-form, acme/ui/button, or http://localhost:3000/r/editor.json.

dependencies field for npm package dependencies

List all npm package dependencies in the dependencies field of a registry item. A dependency is the name of a package in the registry, e.g., zod, sonner. To set a version, use the format name@version, e.g., zod@^3.20.0.

Registry item imports must use @/registry path

Imports in registry items should always use the @/registry path, for example: import { HelloWorld } from "@/registry/default/hello-world/hello-world"

Registry item file organization guideline

Ideally, place files within a registry item in components, hooks, or lib directories.

Install shadcn as runtime dependency for dynamic registries

To use loadRegistry and loadRegistryItem for dynamic registry serving, install shadcn as a runtime dependency with: npm install shadcn

registry:base is a complete design system

A registry:base item defines a full design system base with dependencies, CSS variables, and configuration. It supports an optional config field with properties for style, iconLibrary, rsc, tsx, rtl, menuColor, menuAccent, tailwind settings (baseColor, css, prefix), aliases for components/utils/ui/lib/hooks, and custom registries object.

registry:theme custom theme structure

A registry:theme item defines CSS variables for light and dark modes using OKLch color values. Required CSS variables typically include background, foreground, primary, primary-foreground, ring, sidebar-primary, sidebar-primary-foreground, and sidebar-ring. Example uses OKLch format like "oklch(0.546 0.245 262.881)".

registry:block installs multiple components together

A registry:block item can install multiple files and components as a unit. It specifies registryDependencies (like button, card, input, label) and includes a files array where each file has a path, type (registry:page, registry:component, etc.), and optional target location to install the file in the project.

CSS component layer styles in registry items

Registry items can define component layer styles using @layer components. Example defining a card component: ```json "css": { "@layer components": { "card": { "background-color": "var(--color-white)", "border-radius": "var(--rounded-lg)", "padding": "var(--spacing-6)", "box-shadow": "var(--shadow-xl)" } } } ```

registry:ui component with CSS variables example

A registry:ui item can define CSS variables for light and dark modes. Example sidebar component with cssVars defining sidebar-background, sidebar-foreground, and sidebar-border in OKLch format: ```json { "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "sidebar", "type": "registry:ui", "dependencies": ["radix-ui"], "registryDependencies": ["button", "separator", "sheet", "tooltip"], "files": [ { "path": "ui/sidebar.tsx", "content": "...", "type": "registry:ui" } ], "cssVars": { "light": { "sidebar-background": "oklch(0.985 0 0)", "sidebar-foreground": "oklch(0.141 0.005 285.823)", "sidebar-border": "oklch(0.92 0.004 286.32)" }, "dark": { "sidebar-background": "oklch(0.141 0.005 285.823)", "sidebar-foreground": "oklch(0.985 0 0)", "sidebar-border": "oklch(0.274 0.006 286.033)" } } } ```

registry:lib utility library example

A registry:lib item shares helper functions and non-component code. Example utils library with clsx and tailwind-merge: ```json { "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "utils", "type": "registry:lib", "dependencies": ["clsx", "tailwind-merge"], "files": [ { "path": "lib/utils.ts", "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}", "type": "registry:lib" } ] } ```

Give your agent this brain