---
title: "Project Structure"
description: "Fumadocs utilizes a monorepo architecture managed via pnpm workspaces, designed to decouple documentation core logic, UI implementations, and ecosystem integrations. This structure solves the compl..."
last_updated: "2026-07-02T09:46:38.964302+00:00"
canonical_url: "https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/orientation/project-structure"
---

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

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

- [packages/core/package.json](https://github.com/blade47/fumadocs/blob/main/packages/core/package.json)
- [packages/radix-ui/package.json](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/package.json)
- [packages/base-ui/package.json](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/package.json)
- [packages/typescript/src/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/typescript/src/index.ts)
- [packages/cli/src/commands/shared.ts](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/commands/shared.ts)
- [packages/base-ui/registry/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/registry/index.ts)
- [packages/sanity/registry/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/sanity/registry/index.ts)
- [packages/radix-ui/registry/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/registry/index.ts)
- [packages/doc-gen/src/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/doc-gen/src/index.ts)
- [packages/core/src/page-tree/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/core/src/page-tree/index.ts)
- [packages/shared/package.json](https://github.com/blade47/fumadocs/blob/main/packages/shared/package.json)
- [packages/story/src/type-tree/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/story/src/type-tree/index.ts)
- [packages/local-md/package.json](https://github.com/blade47/fumadocs/blob/main/packages/local-md/package.json)
- [packages/python/src/generated.ts](https://github.com/blade47/fumadocs/blob/main/packages/python/src/generated.ts)
- [packages/shadcn/src/types.ts](https://github.com/blade47/fumadocs/blob/main/packages/shadcn/src/types.ts)
- [package.json](https://github.com/blade47/fumadocs/blob/main/package.json)
- [packages/vite-data/package.json](https://github.com/blade47/fumadocs/blob/main/packages/vite-data/package.json)
- [packages/stf/src/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/stf/src/index.ts)
- [packages/mdx/src/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/mdx/src/index.ts)
- [packages/python/src/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/python/src/index.ts)
- [packages/api-docs/package.json](https://github.com/blade47/fumadocs/blob/main/packages/api-docs/package.json)
- [packages/core/tsdown.config.ts](https://github.com/blade47/fumadocs/blob/main/packages/core/tsdown.config.ts)
- [packages/asyncapi/src/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/index.ts)
- [packages/typescript/src/ui/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/typescript/src/ui/index.ts)
- [packages/python/fumapy/mksource/models.py](https://github.com/blade47/fumadocs/blob/main/packages/python/fumapy/mksource/models.py)
- [packages/core/src/search/server.ts](https://github.com/blade47/fumadocs/blob/main/packages/core/src/search/server.ts)
- [packages/create-app/src/constants.ts](https://github.com/blade47/fumadocs/blob/main/packages/create-app/src/constants.ts)
- [pnpm-workspace.yaml](https://github.com/blade47/fumadocs/blob/main/pnpm-workspace.yaml)
- [packages/preview/src/config/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/preview/src/config/index.ts)
- [packages/story/package.json](https://github.com/blade47/fumadocs/blob/main/packages/story/package.json)
</details>

Fumadocs utilizes a monorepo architecture managed via `pnpm` workspaces, designed to decouple documentation core logic, UI implementations, and ecosystem integrations. This structure solves the complexity of managing shared documentation primitives (like page trees, search indexing, and MDX processing) alongside multiple frontend UI libraries and build-tool plugins.

The project is segmented into distinct packages under the `packages/` directory. Each package serves a single responsibility: `fumadocs-core` provides the foundation, while specialized packages like `fumadocs-ui` (Radix UI based) or `base-ui` (Base UI based) offer alternative implementations of visual components. Integrations for specific ecosystems—such as MDX, TypeScript documentation, AsyncAPI, and Python source generation—are likewise separated, ensuring that a consumer only installs the dependencies required for their specific use case.

This modularity is enforced through a strict `tsdown` configuration and explicit `exports` definitions in each `package.json`. By isolating cross-cutting concerns like search, navigation, and i18n into their own sub-paths, the project minimizes bundle size for end users and allows for independent versioning and testing of components, providing a robust surface area for extensibility and integration.

## Monorepo Workspace Configuration
The workspace is managed by `pnpm-workspace.yaml`, which defines the scope of packages available for development. The root `package.json` coordinates cross-package tasks using `turbo`, facilitating global build, lint, and test cycles.

| Task | Command | Scope |
| :--- | :--- | :--- |
| Build | `turbo run build` | All packages |
| Test | `vitest` | Root test runner |
| Version | `changeset version` | Changelog management |

Sources: [pnpm-workspace.yaml:1-4](https://github.com/blade47/fumadocs/blob/main/pnpm-workspace.yaml#L1-L4), [package.json:5-17](https://github.com/blade47/fumadocs/blob/main/package.json#L5-L17)

## Core Package Architecture
`fumadocs-core` acts as the engine, housing fundamental documentation structures. It is built using `tsdown`, which generates ESM output. The core package structure emphasizes functional composition, with modules like `page-tree`, `search`, and `mdx-plugins` providing the logic for transforming source content into renderable documentation structures.

```mermaid
flowchart TD
    Core["fumadocs-core"]
    Core --> PT["page-tree"]
    Core --> Search["search (server/client)"]
    Core --> MDX["mdx-plugins"]
    Core --> Framework["framework (next, waku, etc)"]
```
Sources: [packages/core/package.json:20-97](https://github.com/blade47/fumadocs/blob/main/packages/core/package.json#L20-L97), [packages/core/tsdown.config.ts:10-31](https://github.com/blade47/fumadocs/blob/main/packages/core/tsdown.config.ts#L10-L31)

## UI Component Registry
Fumadocs utilizes a registry-based approach for UI components, similar to CLI-driven distribution patterns. The `packages/base-ui` and `packages/radix-ui` registries define how components are structured, listed, and written to user codebases.

The registry logic uses a `findSlotComponents` function imported from the `shared` module to dynamically discover and register UI components. This allows the CLI to manage component installation without manual registration of every file.

```mermaid
classDiagram
    class Registry {
        +string name
        +string dir
        +Object[] components
        +Object dependencies
    }
```
Sources: [packages/base-ui/registry/index.ts:9-347](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/registry/index.ts#L9-L347), [packages/radix-ui/registry/index.ts:9-346](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/registry/index.ts#L9-L346)

## Content and Source Generation
Specialized packages handle non-React content sources. For instance, the `packages/python` package provides a robust interface for generating documentation from Python source code, utilizing a `ModuleInterface` that defines how docstrings and metadata are structured.

> [!NOTE]
> The `DocstringSection` type in `packages/python/src/generated.ts` uses a tagged union pattern (`kind`) to differentiate between text blocks, code examples, and admonitions, allowing the rendering engine to correctly map complex docstrings to React components.

Sources: [packages/python/src/generated.ts:43-69](https://github.com/blade47/fumadocs/blob/main/packages/python/src/generated.ts#L43-L69), [packages/python/fumapy/mksource/models.py:6-61](https://github.com/blade47/fumadocs/blob/main/packages/python/fumapy/mksource/models.py#L6-L61)

## Ecosystem Integration Strategy
The system handles environment-specific requirements through internal `peerDependenciesMeta` and `inlinedDependencies` fields. This ensures that packages can rely on necessary runtime dependencies (like `react` or `next`) while marking them as optional for consumers who might use alternative configurations.

| Strategy | Implementation Detail | Purpose |
| :--- | :--- | :--- |
| Inlining | `inlinedDependencies` | Reduce consumer bundle resolution overhead |
| Optionality | `peerDependenciesMeta` | Prevent forced installation of unused ecosystem packages |
| Aliasing | `npm:@fumadocs/base-ui` | Maintain backwards compatibility during renames |

Sources: [packages/core/package.json:162-247](https://github.com/blade47/fumadocs/blob/main/packages/core/package.json#L162-L247), [packages/base-ui/registry/index.ts:344](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/registry/index.ts#L344)

## CLI and Code Generation
The CLI tooling acts as the glue for the registry system, using `packages/cli/src/commands/shared.ts` to map internal UI names to registry keys. This allows the `create-app` package to standardize initialization across different template types (e.g., Next.js, Waku, TanStack Start).

### Lifecycle Walkthrough: Initializing an App
1. The user runs an installation command targeting a template (e.g., `+next+fuma-docs-mdx`).
2. `create-app/src/constants.ts` resolves the workspace versions for the selected template.
3. The CLI identifies the `rootProviderPath` (e.g., `app/layout.tsx`).
4. The requested registry component (from `base-ui` or `radix-ui`) is copied into the consumer directory according to the `target` path definition in the registry.

Sources: [packages/create-app/src/constants.ts:34-80](https://github.com/blade47/fumadocs/blob/main/packages/create-app/src/constants.ts#L34-L80), [packages/cli/src/commands/shared.ts:1-4](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/commands/shared.ts#L1-L4)

## Related

- [Overview](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/orientation/overview)
- [Quick Start](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/orientation/quick-start)


## Sitemap

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