Difference Between registry:ui, registry:lib, and registry:block in shadcn/ui
The shadcn/ui registry uses registry:ui for standalone components like buttons, registry:lib for utility functions like cn, and registry:block for complete page layouts like dashboards that bundle multiple files.
The shadcn/ui repository organizes every reusable asset—components, helpers, and full-page templates—into a structured registry. Each entry carries a type field that dictates how the CLI handles installation, where files land in your project, and what dependencies are pulled. Understanding the distinction between registry:ui, registry:lib, and registry:block ensures you scaffold the right code for your use case.
Understanding the shadcn/ui Registry Type System
The registry’s type safety is enforced by registryItemTypeSchema in packages/shadcn/src/registry/schema.ts【/cache/repos/github.com/shadcn-ui/ui/main/packages/shadcn/src/registry/schema.ts#L73-L78】. This schema enumerates valid types including registry:ui, registry:lib, registry:block, and registry:component. When you run npx shadcn-ui@latest add, the CLI reads the type field to determine the installation strategy.
registry:ui: Standalone UI Components
File Location and Schema
UI components are defined in deprecated/www/registry/registry-ui.ts【/cache/repos/github.com/shadcn-ui/ui/main/deprecated/www/registry/registry-ui.ts#L4-L13】. Each entry has type: "registry:ui" and maps to one or more files under ui/*.tsx. These are self-contained React components with optional Tailwind CSS configurations and third-party dependencies.
CLI Installation Behavior
When you add a UI component, the CLI copies the source file into your project’s components/ui/ directory and merges any Tailwind snippets into your global CSS.
npx shadcn-ui@latest add button
This generates src/components/ui/button.tsx:
import * as React from "react"
import { cn } from "@/lib/utils"
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: "default" | "destructive"
}
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant = "default", ...props }, ref) => (
<button
ref={ref}
className={cn(
"inline-flex items-center justify-center rounded-md px-4 py-2",
variant === "destructive" && "bg-red-600 text-white",
className
)}
{...props}
/>
)
)
Button.displayName = "Button"
registry:lib: Utility Libraries
Purpose and Structure
The registry:lib type handles utility functions and type definitions that contain no UI markup. These entries live in deprecated/www/registry/registry-lib.ts【/cache/repos/github.com/shadcn-ui/ui/main/deprecated/www/registry/registry-lib.ts#L3-L11】 and typically export helpers like the cn function for merging Tailwind classes.
Installation and Usage
When you add a library, the CLI places files into a lib/ folder at your project root, allowing standard ES module imports.
npx shadcn-ui@latest add utils
This creates src/lib/utils.ts:
export function cn(...classes: (string | false | null | undefined)[]) {
return classes.filter(Boolean).join(" ")
}
You then reference these utilities in UI components:
import { cn } from "@/lib/utils"
registry:block: Prefabricated Page Blocks
Complexity and Composition
Blocks are high-level, ready-to-use page layouts defined in deprecated/www/registry/registry-blocks.ts【/cache/repos/github.com/shadcn-ui/ui/main/deprecated/www/registry/registry-blocks.ts#L4-L10】. A registry:block entry bundles multiple file types: a page file (registry:page), data files (registry:file), and numerous registry:component entries that compose the layout.
Dashboard Example Structure
Adding a block scaffolds an entire application folder with all dependencies wired together.
npx shadcn-ui@latest add dashboard-01
This generates a complete directory structure:
app/
└─ dashboard/
├─ page.tsx ← registry:page
├─ data.json ← registry:file
└─ components/
├─ app-sidebar.tsx ← registry:component
├─ chart-area-interactive.tsx
└─ …
The block’s registryDependencies array ensures the CLI automatically pulls in every required sub-component without manual installation.
registry:component: The Atomic Building Block
While registry:ui, registry:lib, and registry:block are the primary types you interact with, the registry also uses registry:component as an internal atomic unit. These entries represent single component files that are never added directly via the CLI. Instead, they are referenced by registry:ui or registry:block entries through the registryDependencies field, allowing multiple parent items to share common sub-components without duplication.
Summary
registry:uidefines standalone, importable UI components like buttons and accordions that land incomponents/ui/.registry:libdefines utility functions and type definitions without UI markup that land inlib/and are imported as modules.registry:blockdefines complete page layouts that scaffold entire app directories, bundling pages, data files, and multiple components.- Type safety is enforced by
registryItemTypeSchemainpackages/shadcn/src/registry/schema.ts. - Source definitions reside in
deprecated/www/registry/registry-ui.ts,registry-lib.ts, andregistry-blocks.ts.
Frequently Asked Questions
Can I convert a registry:ui component into a registry:block?
No, these types serve different architectural purposes. A registry:ui component is an atomic, reusable element, while a registry:block is a composite layout. However, a block can reference UI components through its registryDependencies array, effectively incorporating them into a larger page structure without changing their underlying type.
Where does the CLI place registry:lib files by default?
The CLI copies registry:lib files into a lib/ directory at your project root, typically resulting in paths like src/lib/utils.ts. This location is standardized so that UI components can reliably import utilities using alias paths such as @/lib/utils.
Are registry:block items self-contained?
Yes, registry:block entries are designed to be self-contained page scaffolds. According to the definitions in deprecated/www/registry/registry-blocks.ts, a single block entry includes the page file (registry:page), data files (registry:file), and all necessary sub-components (registry:component). When you run shadcn add, the CLI generates the complete directory structure required to render the page immediately.
How do I reference registry:component items directly?
You cannot add registry:component items directly via the CLI. These atomic units are internal dependencies referenced by registry:ui or registry:block entries through the registryDependencies field. When you install a parent UI component or block, the CLI automatically resolves and copies any referenced registry:component files into your project.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →