# Difference Between registry:ui, registry:lib, and registry:block in shadcn/ui

> Understand shadcn/ui registry:ui, registry:lib, and registry:block component types. Learn how shadcn/ui organizes components, utilities, and page layouts for efficient web development.

- Repository: [shadcn-ui/ui](https://github.com/shadcn-ui/ui)
- Tags: deep-dive
- Published: 2026-02-26

---

**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`](https://github.com/shadcn-ui/ui/blob/main/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`](https://github.com/shadcn-ui/ui/blob/main/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.

```bash
npx shadcn-ui@latest add button

```

This generates [`src/components/ui/button.tsx`](https://github.com/shadcn-ui/ui/blob/main/src/components/ui/button.tsx):

```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`](https://github.com/shadcn-ui/ui/blob/main/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.

```bash
npx shadcn-ui@latest add utils

```

This creates [`src/lib/utils.ts`](https://github.com/shadcn-ui/ui/blob/main/src/lib/utils.ts):

```ts
export function cn(...classes: (string | false | null | undefined)[]) {
  return classes.filter(Boolean).join(" ")
}

```

You then reference these utilities in UI components:

```tsx
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`](https://github.com/shadcn-ui/ui/blob/main/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.

```bash
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:ui`** defines standalone, importable UI components like buttons and accordions that land in `components/ui/`.
- **`registry:lib`** defines utility functions and type definitions without UI markup that land in `lib/` and are imported as modules.
- **`registry:block`** defines complete page layouts that scaffold entire app directories, bundling pages, data files, and multiple components.
- **Type safety** is enforced by `registryItemTypeSchema` in [`packages/shadcn/src/registry/schema.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/registry/schema.ts).
- **Source definitions** reside in [`deprecated/www/registry/registry-ui.ts`](https://github.com/shadcn-ui/ui/blob/main/deprecated/www/registry/registry-ui.ts), [`registry-lib.ts`](https://github.com/shadcn-ui/ui/blob/main/registry-lib.ts), and [`registry-blocks.ts`](https://github.com/shadcn-ui/ui/blob/main/registry-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`](https://github.com/shadcn-ui/ui/blob/main/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`](https://github.com/shadcn-ui/ui/blob/main/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.