---
title: "shadcn/ui Docs Registry"
description: "The @fumadocs/shadcn package provides an integration layer that connects shadcn UI registry definitions with Fumadocs documentation projects. It resolves component files, dependencies, and configur..."
last_updated: "2026-10-12T07:53:59.831064+00:00"
canonical_url: "https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/content-sources/shadcn-ui-docs-registry"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [packages/base-ui/registry/index.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/base-ui/registry/index.ts)
- [packages/radix-ui/registry/index.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/registry/index.ts)
- [packages/cli/src/commands/shared.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/cli/src/commands/shared.ts)
- [packages/shadcn/src/manual-installation.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/manual-installation.ts)
- [packages/shadcn/src/rsc.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/rsc.tsx)
- [packages/shadcn/src/index.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/index.ts)
- [packages/cli/src/commands/add.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/cli/src/commands/add.ts)
- [packages/sanity/registry/index.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/sanity/registry/index.ts)
- [packages/shadcn/package.json](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/package.json)
- [packages/radix-ui/package.json](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/package.json)
- [packages/shared/registry.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shared/registry.ts)
- [packages/asyncapi/src/ui/index.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/asyncapi/src/ui/index.tsx)
- [packages/cli/src/registry/installer.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/cli/src/registry/installer.ts)
- [packages/cli/src/commands/customise.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/cli/src/commands/customise.ts)
- [packages/preview/src/pages/...slugs.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/preview/src/pages/%5B...slugs%5D.tsx)
- [packages/content/src/index.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/content/src/index.ts)
- [packages/cli/src/registry/plugins/preserve.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/cli/src/registry/plugins/preserve.ts)
- [packages/openapi/src/ui/base.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/openapi/src/ui/base.tsx)
- [packages/base-ui/package.json](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/base-ui/package.json)
- [packages/create-app/src/plugins/orama-cloud.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/create-app/src/plugins/orama-cloud.ts)
- [packages/cli/src/index.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/cli/src/index.ts)
- [packages/create-app/src/plugins/ai.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/create-app/src/plugins/ai.ts)
- [packages/preview/src/components/provider.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/preview/src/components/provider.tsx)
- [packages/api-docs/package.json](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/api-docs/package.json)
- [packages/base-ui/src/provider/waku.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/base-ui/src/provider/waku.tsx)
- [packages/preview/package.json](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/preview/package.json)
- [packages/create-app/scripts/sync.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/create-app/scripts/sync.ts)
- [packages/core/package.json](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/package.json)
- [packages/python/src/components/index.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/python/src/components/index.tsx)
- [packages/openapi/package.json](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/openapi/package.json)
</details>

## Overview

The `@fumadocs/shadcn` package provides an integration layer that connects `shadcn` UI registry definitions with Fumadocs documentation projects. It resolves component files, dependencies, and configuration snippets for manual or automated installation.

Sources: [packages/shadcn/package.json:1-8](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/package.json#L1-L8), [packages/shadcn/src/index.ts:10-24](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/index.ts#L10-L24)

By parsing built registry items and processing component collections across multiple UI libraries like `fumadocs/base-ui` and `fumadocs/radix-ui`, it enables seamless component discovery and code generation.

Sources: [packages/base-ui/registry/index.ts:9-14](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/base-ui/registry/index.ts#L9-L14), [packages/radix-ui/registry/index.ts:9-14](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/registry/index.ts#L9-L14), [packages/shadcn/src/manual-installation.ts:58-64](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/manual-installation.ts#L58-L64)

## Registry Item Schema and Definitions

### Built Registry Structure and Component Metadata

Documentation and UI components within the integration are modeled through built registry item types, file specifications, and common utility definitions. Each entry in the registry maps specific file paths, targets, and internal component types such as layout slots or shared utilities.

| Component / File Type | Identifier / Path | Target Location | Description |
| :--- | :--- | :--- | :--- |
| Slot Component | `slots/*` | `<dir>/layouts/**/slots/*` | Discovered layout slot components from layout directories |
| URL Utility | `urls` | `utils/urls.ts` | Common URL helper utility |
| Class Name Utility | `cn` | `utils/cn.ts` | Class merging utility |
| Reference Merger | `merge-refs` | `utils/merge-refs.ts` | DOM ref merging utility |
| [Table of Contents](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/ui-layouts/table-of-contents) | `toc` | `<dir>/toc/*.tsx` | Clerk, default, and index Table of Contents components |

Sources: [packages/shared/registry.ts:5-83](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shared/registry.ts#L5-L83)

### Registry Types and Manual Installation Snippets

The manual installation system defines union types for generated documentation snippets, file payloads, and package manager commands. Snippets are categorized by their kind, determining how they render in documentation views.

```typescript
export type ManualInstallationSnippet =
  | {
      lang: string;
      code: string;
      path: string;
      title: string;
      kind: 'file';
    }
  | {
      kind: 'docs';
      content: string;
    }
  | {
      kind: 'cssVars' | 'css' | 'tailwind' | 'envVars';
      lang: string;
      code: string;
    }
  | {
      kind: 'dependencies' | 'devDependencies' | 'registryDependencies';
      lang: string;
      codeTabs: Record<PM, string>;
      dependencies: string[];
    };
```

Sources: [packages/shadcn/src/manual-installation.ts:12-42](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/manual-installation.ts#L12-L42)

> [!NOTE]
> The `includeRegistryDependencies` option defaults to `true` when fetching installation options, automatically queueing and resolving local registry dependencies alongside primary items.

Sources: [packages/shadcn/src/manual-installation.ts:51-63](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/manual-installation.ts#L51-L63)

## Component Discovery Across UI Libraries

### Glob Discovery and Slot Collection

The shared registry logic uses `tinyglobby` to scan the local filesystem for layout slot components within layout subdirectories. By executing a glob pattern against the target components directory, it discovers custom layout slots and dynamically constructs corresponding registry components with unlisted flags.

```typescript
export async function findSlotComponents(dir: string): Promise<Component[]> {
  const slots: Component[] = [];

  for (const file of await glob('layouts/**/slots/*', { cwd: dir })) {
    const relativePath = path.relative('layouts', file);
    const name = relativePath
      .split(path.sep)
      .filter((v) => v !== 'slots')
      .join('/')
      .slice(0, -path.extname(relativePath).length);

    slots.push({
      name: `slots/${name}`,
      unlisted: true,
      files: [
        {
          path: file,
          type: 'layout',
          target: path.join('<dir>', relativePath),
        },
      ],
    });
  }

  return slots;
}
```

Sources: [packages/shared/registry.ts:1-30](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shared/registry.ts#L1-L30)

> [!NOTE]
> The dynamic slot discovery function transforms file paths by removing intermediate segment markers such as `slots` and stripping file extensions, producing standardized slot identifiers like `slots/docs/header`.

Sources: [packages/shared/registry.ts:8-15](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shared/registry.ts#L8-L15)

### Library Registry Integration

Both the `fumadocs/base-ui` and `fumadocs/radix-ui` registries resolve their base component directory relative to the current file URL using Node's path utilities. Each library registry aggregates common shared utilities, dynamically evaluated slot components from `findSlotComponents`, and unlisted layout groups or individual UI components.

| Registry Package | Registry Name Property | Base Source Directory (`dir`) | Core Shared Components Included |
| :--- | :--- | :--- | :--- |
| `packages/base-ui/registry/index.ts` | `fumadocs/base-ui` | `../src` | `urls`, `cn`, `merge-refs`, `toc` |
| `packages/radix-ui/registry/index.ts` | `fumadocs/radix-ui` | `../src` | `urls`, `cn`, `merge-refs`, `toc` |

Sources: [packages/base-ui/registry/index.ts:1-14](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/base-ui/registry/index.ts#L1-L14), [packages/radix-ui/registry/index.ts:1-14](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/registry/index.ts#L1-L14), [packages/shared/registry.ts:32-83](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shared/registry.ts#L32-L83)

> [!WARNING]
> In the shadcn CLI integration, the exact order of entries within the component array matters because it dictates the sequence in which import paths and dependencies are written to the consumer codebase.

Sources: [packages/base-ui/registry/index.ts:8](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/base-ui/registry/index.ts#L8), [packages/radix-ui/registry/index.ts:8](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/registry/index.ts#L8)

## Manual Installation Pipeline and Formatting

### Resolving Dependencies and Collecting Items

The manual installation pipeline is initialized via `createShadcnDocs`, which binds a `RegistryContext` containing the `registryPath` and root directory. When `getManualInstallation` executes with a given registry item name, it delegates to `collectItems` to recursively traverse and resolve local dependencies, accumulating items into a collection queue.

```typescript
export async function getManualInstallation(
  this: RegistryContext,
  options: GetManualInstallationOptions,
): Promise<ManualInstallationSnippet[]> {
  const { name, includeRegistryDependencies = true } = options;
  const items = await collectItems.call(this, name, includeRegistryDependencies);
  if (items.length === 0) return [];

  const snippets: ManualInstallationSnippet[] = [];
  const dependencies = new Set<string>();
  const devDependencies = new Set<string>();
  const registryDependencies = new Set<string>();
```
Sources: [packages/shadcn/src/manual-installation.ts:58-69](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/manual-installation.ts#L58-L69)

> [!WARNING]
> If a registry item file cannot be read from the filesystem during queue traversal, `collectItems` catches the error and assigns a `null` value in the lookup map, safely skipping broken or missing paths without halting execution.

Sources: [packages/shadcn/src/manual-installation.ts:141-158](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/manual-installation.ts#L141-L158)

### Formatting Snippets and Display Paths

Once item collection finishes, the pipeline iterates through each registry item to extract documentation notes, environment variables, CSS variables, CSS rules, Tailwind configurations, and constituent file contents. File display paths are normalized according to their specific registry type classification.

| Registry File Type | Default Target Path Prefix | Example Resolved Output |
| :--- | :--- | :--- |
| `registry:ui` | `components/ui/` | `components/ui/button.tsx` |
| `registry:component` | `components/` | `components/card.tsx` |
| `registry:hook` | `lib/hooks/` | `lib/hooks/use-mobile.ts` |
| `registry:lib` | `lib/` | `lib/utils.ts` |
| `registry:block` | `components/` | `components/hero.tsx` |

Sources: [packages/shadcn/src/manual-installation.ts:218-236](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/manual-installation.ts#L218-L236)

> [!TIP]
> If a registry file defines an explicit `target` property starting with `~/`, the leading tilde and slash are sliced off to produce a clean relative display path for the generated code snippet.

Sources: [packages/shadcn/src/manual-installation.ts:218-221](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/manual-installation.ts#L218-L221)

## Server Components for Code Snippets

### Rendering Syntax-Highlighted Code Blocks and Documentation Notes

The `Snippet` asynchronous React Server Component handles the presentation of individual `ManualInstallationSnippet` objects by evaluating their item types and rendering appropriate UI elements. When an item has a `kind` of `'docs'`, it bypasses [syntax highlighting](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/core-architecture/syntax-highlighting) and outputs the descriptive text directly inside a paragraph styled with text colors and preserved whitespace.

```tsx
export async function Snippet({ item }: { item: ManualInstallationSnippet }) {
  if (item.kind === 'docs') {
    return <p className="text-fd-muted-foreground text-sm whitespace-pre-wrap">{item.content}</p>;
  }
```
Sources: [packages/shadcn/src/rsc.tsx:28-31](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/rsc.tsx#L28-L31)

> [!NOTE]
> Standard code snippets receive syntax highlighting through `ServerCodeBlock` alongside an array of pre-configured Shiki transformers consisting of `transformerNotationDiff()` and `transformerIcon()`.

Sources: [packages/shadcn/src/rsc.tsx:10-12](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/rsc.tsx:10-12), [packages/shadcn/src/rsc.tsx:59-66](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/rsc.tsx#L59-L66)

### File Title Mapping and Dependency Tabs

To provide contextual headers for standard code snippets, the `getTitle` helper function inspects item kinds and maps them to fixed filenames or dynamic file paths. For dependency and package installation snippets containing multiple tabs, `Snippet` renders interactive code block tabs via `CodeBlockTabs` and `CodeBlockTabsTrigger` components.

| Item Kind | Mapped Title or Filename |
| :--- | :--- |
| `file` | `item.path` |
| `cssVars` / `css` | `globals.css` |
| `envVars` | `.env.local` |
| `tailwind` | `tailwind.config.js` |

Sources: [packages/shadcn/src/rsc.tsx:14-26](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/rsc.tsx:14-26), [packages/shadcn/src/rsc.tsx:57-65](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/rsc.tsx:57-65)

```tsx
switch (item.kind) {
  case 'dependencies':
  case 'devDependencies':
  case 'registryDependencies':
    const tabs = Object.entries(item.codeTabs);

    return (
      <CodeBlockTabs defaultValue={tabs[0][0]}>
        <CodeBlockTabsList>
          {tabs.map(([t]) => (
            <CodeBlockTabsTrigger key={t} value={t}>
              {t}
            </CodeBlockTabsTrigger>
          ))}
        </CodeBlockTabsList>
        {tabs.map(([k, v]) => (
          <CodeBlockTab key={k} value={k}>
            <ServerCodeBlock code={v} lang={item.lang} />
          </CodeBlockTab>
        ))}
      </CodeBlockTabs>
    );
}
```
Sources: [packages/shadcn/src/rsc.tsx:33-55](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/rsc.tsx:33-55)

> [!TIP]
> Dependency and devDependency code blocks utilize `Object.entries(item.codeTabs)` to populate multi-package installer tabs, setting the default active tab to the first entry in the collection.

Sources: [packages/shadcn/src/rsc.tsx:37-40](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/shadcn/src/rsc.tsx:37-40)

## CLI Automated Installation Integration

### UI Registry Endpoint Mapping and Client Resolution

The [Fumadocs CLI](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/developer-tooling/fumadocs-cli) defines default UI registry mappings in shared configuration modules, mapping identifiers such as `'base-ui'` to `'fumadocs/base-ui'` and `'radix-ui'` to `'fumadocs/radix-ui'`. 

Sources: [packages/cli/src/commands/shared.ts:1-4](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/cli/src/commands/shared.ts#L1-L4)

During command execution, the `createClientFromDir` utility function resolves registry directory parameters against predefined shortcuts, instantiating either an `HttpRegistryConnector` or a `LocalRegistryConnector` depending on whether the target path begins with an HTTP protocol schema.

| Shortcut Key | Resolved URL Target |
| :--- | :--- |
| `:preview` | `https://preview.fumadocs.dev/registry` |
| `:dev` | `http://localhost:3000/registry` |
| *default* | `https://fumadocs.dev/registry` |

Sources: [packages/cli/src/index.ts:39-42](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/cli/src/index.ts#L39-L42), [packages/cli/src/index.ts:108-114](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/cli/src/index.ts#L108-L114)

```mermaid
flowchart TD
    A[Input Dir Option] --> B{Matches Shortcut?}
    B -- Yes --> C[Resolve Shortcut URL]
    B -- No --> D{Starts with http:// or https://?}
    C --> D
    D -- Yes --> E[HttpRegistryConnector]
    D -- No --> F[LocalRegistryConnector]
```
Sources: [packages/cli/src/index.ts:108-114](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/cli/src/index.ts#L108-L114)

### Template Plugin and Installer Integration

The application creation toolkit integrates registry components directly into newly scaffolded projects via asynchronous template plugins. For instance, the AI search plugin initializes a `FumadocsComponentInstaller` coupled with an `HttpRegistryConnector` pointing to the main registry endpoint to fetch and install required components like `ai/${provider}`.

```typescript
export function ai(provider: 'openrouter' | 'llmgateway' | 'inkeep'): TemplatePlugin {
  return {
    async afterWrite() {
      const config = await getDefaultConfig(this.dest);
      const installer = new FumadocsComponentInstaller(
        new HttpRegistryConnector('https://fumadocs.dev/registry'),
        config,
        this.dest,
      );

      try {
        const deps = await installer.install(`ai/${provider}`).then((res) => res.deps());
        if (deps.hasRequired()) await deps.writeRequired();

        await addAIChat(this);
        await fs.writeFile(path.join(this.dest, '.env.local'), `${envKey[provider]}=`);
      } catch (e) {
        console.error(e);
      }
    },
  };
}
```
Sources: [packages/create-app/src/plugins/ai.ts:16-37](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/create-app/src/plugins/ai.ts#L16-L37)

> [!NOTE]
> Environment variables for AI providers are programmatically mapped through the `envKey` record, linking `'openrouter'`, `'llmgateway'`, and `'inkeep'` directly to `OPENROUTER_API_KEY`, `LLM_GATEWAY_API_KEY`, and `INKEEP_API_KEY` respectively.

Sources: [packages/create-app/src/plugins/ai.ts:10-14](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/create-app/src/plugins/ai.ts#L10-L14)

Layout preservation plugins intercept component installation stacks to maintain references to standard layout specifications unless explicitly requested via direct installation. The `pluginPreserveLayouts` hook filters out child sub-components matching predefined layout names and rewrites local file imports to point directly to package-level UI modules like `fumadocs-ui/layouts/docs`.

```typescript
export function pluginPreserveLayouts(): InstallerPlugin {
  const layoutNames = [
    'layouts/home',
    'layouts/flux',
    'layouts/notebook',
    'layouts/docs',
    'layouts/shared',
  ];
```
Sources: [packages/cli/src/registry/plugins/preserve.ts:6-13](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/cli/src/registry/plugins/preserve.ts#L6-L13), [packages/cli/src/registry/plugins/preserve.ts:43-50](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/cli/src/registry/plugins/preserve.ts#L43-L50)

## Related

- [Base UI Components](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/ui-layouts/base-ui-components)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/llms.txt) for all pages in this wiki.
