---
title: "Command Line Interface"
description: "The Fumadocs Command Line Interface (CLI) serves as the primary orchestration layer for initializing, configuring, and extending documentation projects. It solves the fragmentation of project scaff..."
last_updated: "2026-07-02T09:46:39.445752+00:00"
canonical_url: "https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/developer-tools/command-line-interface"
---

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

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

- [packages/create-app/src/bin.ts](https://github.com/blade47/fumadocs/blob/main/packages/create-app/src/bin.ts)
- [packages/cli/src/commands/customise.ts](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/commands/customise.ts)
- [packages/cli/src/commands/add.ts](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/commands/add.ts)
- [packages/create-app/src/plugins/ai.ts](https://github.com/blade47/fumadocs/blob/main/packages/create-app/src/plugins/ai.ts)
- [packages/create-app/src/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/create-app/src/index.ts)
- [packages/openapi/package.json](https://github.com/blade47/fumadocs/blob/main/packages/openapi/package.json)
- [packages/api-docs/package.json](https://github.com/blade47/fumadocs/blob/main/packages/api-docs/package.json)
- [packages/local-md/package.json](https://github.com/blade47/fumadocs/blob/main/packages/local-md/package.json)
- [packages/cli/src/registry/installer.ts](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/registry/installer.ts)
- [packages/cli/src/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/index.ts)
- [packages/cli/package.json](https://github.com/blade47/fumadocs/blob/main/packages/cli/package.json)
- [packages/preview/src/cli/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/preview/src/cli/index.ts)
- [packages/create-app/package.json](https://github.com/blade47/fumadocs/blob/main/packages/create-app/package.json)
- [packages/doc-gen/src/remark-install.ts](https://github.com/blade47/fumadocs/blob/main/packages/doc-gen/src/remark-install.ts)
- [packages/cli/src/commands/shared.ts](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/commands/shared.ts)
- [packages/preview/package.json](https://github.com/blade47/fumadocs/blob/main/packages/preview/package.json)
- [packages/create-app/scripts/sync.ts](https://github.com/blade47/fumadocs/blob/main/packages/create-app/scripts/sync.ts)
- [packages/cli/src/config.ts](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/config.ts)
- [packages/python/fumapy/__init__.py](https://github.com/blade47/fumadocs/blob/main/packages/python/fumapy/__init__.py)
- [packages/cli/src/registry/plugins/preserve.ts](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/registry/plugins/preserve.ts)
- [packages/python/package.json](https://github.com/blade47/fumadocs/blob/main/packages/python/package.json)
- [packages/python/pyproject.toml](https://github.com/blade47/fumadocs/blob/main/packages/python/pyproject.toml)
- [packages/cli/src/commands/file-tree.ts](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/commands/file-tree.ts)
- [packages/radix-ui/package.json](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/package.json)
- [packages/asyncapi/package.json](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/package.json)
- [packages/base-ui/package.json](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/package.json)
- [packages/create-app-versions/package.json](https://github.com/blade47/fumadocs/blob/main/packages/create-app-versions/package.json)
- [packages/preview/src/styles/globals.css](https://github.com/blade47/fumadocs/blob/main/packages/preview/src/styles/globals.css)
- [packages/twoslash/package.json](https://github.com/blade47/fumadocs/blob/main/packages/twoslash/package.json)
- [packages/create-app/src/constants.ts](https://github.com/blade47/fumadocs/blob/main/packages/create-app/src/constants.ts)
</details>

The Fumadocs Command Line Interface (CLI) serves as the primary orchestration layer for initializing, configuring, and extending documentation projects. It solves the fragmentation of project scaffolding by providing a unified, interactive entry point that handles framework-specific requirements—such as template selection, dependency installation, and directory structure setup—without requiring manual boilerplate configuration.

Architecturally, the CLI is split into specialized packages: `create-app` for initial bootstrapping and `@fumadocs/cli` for ongoing project maintenance. It utilizes a plugin-based system to handle modular concerns like AI integration, linting configurations, and layout customization, ensuring that the CLI remains maintainable while supporting diverse frontend ecosystems (Next.js, Waku, React Router, and Tanstack Start).

Beyond scaffolding, the CLI provides deep operational utilities for managing UI components. It interacts with registries to fetch, install, and update UI components into a local project while strictly respecting user configuration defined in `cli.json`. By providing interactive prompts, the CLI abstracts complex configuration choices into a coherent user journey, ensuring consistent project standards across the Fumadocs ecosystem.

## CLI Architecture and Control Flow

The CLI operates by parsing user inputs via `commander`, which then dispatches tasks to specific command modules. The core logic for project management is decentralized into specialized commands like `add` and `customise`.

```mermaid
flowchart TD
    A[User CLI Entry] --> B{Command Dispatched}
    B -->|add| C[Install Component]
    B -->|customise| D[Layout Configuration]
    B -->|create| E[Scaffold Project]
    C --> F[FumadocsComponentInstaller]
    D --> F
    E --> G[Template Plugin Pipeline]
    F --> H[File System Operations]
    G --> H
```
Sources: [packages/cli/src/index.ts:15-116](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/index.ts#L15-L116), [packages/create-app/src/bin.ts:56-300](https://github.com/blade47/fumadocs/blob/main/packages/create-app/src/bin.ts#L56-L300)

## Component Installation

The `FumadocsComponentInstaller` class encapsulates the logic for adding components to an existing project. It acts as the bridge between the remote component source and the local file system.

The installer uses a plugin architecture to preserve critical layout components. During installation, the `pluginPreserveLayouts` plugin acts as a safety gate.

```typescript
// Installer configuration logic in packages/cli/src/registry/installer.ts
this.interactive = { name, spin };
const deps = await super.install(name, subRegistry).then((res) => res.deps());
spin.stop(picocolors.bold(picocolors.greenBright(`${name} installed`)));
```
Sources: [packages/cli/src/registry/installer.ts:54-65](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/registry/installer.ts#L54-L65)

> [!WARNING]
> The installer enforces a strict state invariant: it throws an error if a new installation attempt occurs while an installation is already in progress (`if (this.interactive) throw new Error(...)`). This prevents race conditions in file system modifications.
Sources: [packages/cli/src/registry/installer.ts:55-57](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/registry/installer.ts#L55-L57)

## Configuration Lifecycle

The CLI maintains configuration via `cli.json`. The `createOrLoadConfig` function is the primary source of truth, performing a check to see if a file exists before parsing.

| Property | Default | Description |
| :--- | :--- | :--- |
| `uiLibrary` | `radix-ui` | The underlying UI registry used for components. |
| `framework` | Detected | Current project framework (e.g., `next`, `waku`). |
| `baseDir` | `src` or `app` | The base directory for source code. |

Sources: [packages/cli/src/config.ts:62-70](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/config.ts#L62-L70), [packages/cli/src/config.ts:14-55](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/config.ts#L14-L55)

## Plugin Pipeline in `create-app`

The project generator uses a sequential plugin pipeline to transform the initial template. Plugins can define hooks at different stages of the lifecycle.

```mermaid
sequenceDiagram
    participant User
    participant Plugin
    participant Template
    User->>Template: select template
    Template->>Plugin: call template() hook
    Plugin-->>Template: return modified info
    Template->>Template: copy files
    Template->>Plugin: call afterWrite() hook
```
Sources: [packages/create-app/src/index.ts:64-126](https://github.com/blade47/fumadocs/blob/main/packages/create-app/src/index.ts#L64-L126)

## Customization Logic

The `customise` command allows users to replace or rewrite specific parts of the documentation UI. It dynamically fetches registry information and computes target options based on the available layouts in the registry.

The `getSlotCode` helper function contains the logic to generate code blocks for slot replacement. It acts as a router based on the `name` of the slot being customized, returning the correct import and component structure for the user's `layout.tsx`.

Sources: [packages/cli/src/commands/customise.ts:22-179](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/commands/customise.ts#L22-L179), [packages/cli/src/commands/customise.ts:214-381](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/commands/customise.ts#L214-L381)

## File Tree Generation

The `tree` command converts a file system structure into a representable JSON format, which can be output as MDX or JavaScript components.

> [!NOTE]
> When generating the file tree, if a directory contains exactly one sub-item that is a name-indexed node, the command collapses the hierarchy level to reduce nesting in the final MDX output.
Sources: [packages/cli/src/commands/file-tree.ts:27-35](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/commands/file-tree.ts#L27-L35)

```typescript
// Example call to convert a file tree node to MDX
if (item.contents.length === 1 && 'name' in item.contents[0]) {
  const child = item.contents[0];
  return toNode({
    ...child,
    name: `${item.name}/${child.name}`,
  });
}
```
Sources: [packages/cli/src/commands/file-tree.ts:28-34](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/commands/file-tree.ts#L28-L34)

## Related

- [App Templates](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/developer-tools/app-templates)


## Sitemap

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