---
title: "EPUB Exporter"
description: "The EPUB Exporter is a dedicated subsystem for converting Fumadocs documentation into the standard EPUB format. By transforming Markdown/MDX content into semantic HTML and packaging it according to..."
last_updated: "2026-07-02T09:46:39.377752+00:00"
canonical_url: "https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/developer-tools/epub-exporter"
---

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

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

- [packages/epub/src/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/epub/src/index.ts)
- [packages/cli/src/commands/export-epub.ts](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/commands/export-epub.ts)
- [packages/core/src/mdx-plugins/remark-structure.ts](https://github.com/blade47/fumadocs/blob/main/packages/core/src/mdx-plugins/remark-structure.ts)
- [packages/openapi/src/utils/pages/preset-auto.ts](https://github.com/blade47/fumadocs/blob/main/packages/openapi/src/utils/pages/preset-auto.ts)
- [packages/openapi/src/utils/pages/builder.ts](https://github.com/blade47/fumadocs/blob/main/packages/openapi/src/utils/pages/builder.ts)
- [packages/asyncapi/src/generate-file.ts](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/generate-file.ts)
- [packages/core/src/mdx-plugins/rehype-toc.ts](https://github.com/blade47/fumadocs/blob/main/packages/core/src/mdx-plugins/rehype-toc.ts)
- [packages/mdx/src/loaders/mdx/remark-postprocess.ts](https://github.com/blade47/fumadocs/blob/main/packages/mdx/src/loaders/mdx/remark-postprocess.ts)
- [packages/core/src/mdx-plugins/remark-llms.ts](https://github.com/blade47/fumadocs/blob/main/packages/core/src/mdx-plugins/remark-llms.ts)
- [packages/core/src/source/llms.ts](https://github.com/blade47/fumadocs/blob/main/packages/core/src/source/llms.ts)
- [packages/asyncapi/src/utils/pages/preset-auto.ts](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/utils/pages/preset-auto.ts)
- [packages/base-ui/tsdown.config.ts](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/tsdown.config.ts)
- [packages/python/src/convert.ts](https://github.com/blade47/fumadocs/blob/main/packages/python/src/convert.ts)
- [packages/radix-ui/tsdown.config.ts](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/tsdown.config.ts)
- [packages/asyncapi/tsdown.config.ts](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/tsdown.config.ts)
- [packages/epub/src/markdown-to-html.ts](https://github.com/blade47/fumadocs/blob/main/packages/epub/src/markdown-to-html.ts)
- [packages/obsidian/src/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/obsidian/src/index.ts)
- [packages/python/src/write.ts](https://github.com/blade47/fumadocs/blob/main/packages/python/src/write.ts)
- [packages/asyncapi/src/utils/pages/to-text.ts](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/utils/pages/to-text.ts)
- [packages/epub/src/default-styles.ts](https://github.com/blade47/fumadocs/blob/main/packages/epub/src/default-styles.ts)
- [packages/openapi/src/utils/pages/to-text.ts](https://github.com/blade47/fumadocs/blob/main/packages/openapi/src/utils/pages/to-text.ts)
- [packages/epub/src/types.ts](https://github.com/blade47/fumadocs/blob/main/packages/epub/src/types.ts)
- [packages/epub/package.json](https://github.com/blade47/fumadocs/blob/main/packages/epub/package.json)
- [packages/openapi/src/utils/pages/to-static-data.ts](https://github.com/blade47/fumadocs/blob/main/packages/openapi/src/utils/pages/to-static-data.ts)
- [packages/epub/tsdown.config.ts](https://github.com/blade47/fumadocs/blob/main/packages/epub/tsdown.config.ts)
- [packages/content-collections/src/configuration.ts](https://github.com/blade47/fumadocs/blob/main/packages/content-collections/src/configuration.ts)
- [packages/obsidian/src/convert.ts](https://github.com/blade47/fumadocs/blob/main/packages/obsidian/src/convert.ts)
- [packages/preview/src/lib/source/storage.ts](https://github.com/blade47/fumadocs/blob/main/packages/preview/src/lib/source/storage.ts)
- [packages/epub/src/toc-builder.ts](https://github.com/blade47/fumadocs/blob/main/packages/epub/src/toc-builder.ts)
- [packages/content/src/runtime.ts](https://github.com/blade47/fumadocs/blob/main/packages/content/src/runtime.ts)
</details>

The EPUB Exporter is a dedicated subsystem for converting Fumadocs documentation into the standard EPUB format. By transforming Markdown/MDX content into semantic HTML and packaging it according to the IDPF EPUB 3 specification, it allows users to consume documentation offline or on dedicated e-readers, bridging the gap between web-based documentation and portable digital book formats.

The exporter acts as an adapter, taking the `source` object provided by Fumadocs loaders and navigating the site structure to ensure the EPUB's Table of Contents (TOC) mirrors the logical navigation tree of the documentation. This ensures a coherent reading experience, preserving hierarchy and ordering defined in the site metadata.

At its architectural core, the exporter relies on `epub-gen-memory` to construct the EPUB bundle in memory, avoiding unnecessary filesystem I/O during the compilation phase. It employs a post-processing pipeline that transforms Markdown to HTML, resolving relative image paths and applying default styles, making it highly configurable for developers who need to customize the aesthetic or inclusion criteria of their exported books.

## Public Interface: `exportEpub`

The `exportEpub` function is the primary entry point, orchestrating the document collection and conversion process. It accepts an `EpubExportOptions` object, which requires a Fumadocs `source` and various metadata (title, author, publisher).

```typescript
import { exportEpub } from 'fumadocs-epub';
import { source } from '@/lib/source';

const buffer = await exportEpub({
  source,
  title: 'My Documentation',
  author: 'My Team',
  cover: '/cover.png',
});
```

Sources: [packages/epub/src/index.ts:64-150](https://github.com/blade47/fumadocs/blob/main/packages/epub/src/index.ts#L64-L150)

## Page Navigation and Ordering

To generate a sensible EPUB, the exporter must respect the documentation’s navigation structure. The system utilizes `getPagesInTreeOrder`, which recursively flattens the page tree to establish the order of chapters. If the tree contains no navigation items (common in multi-language setups), the exporter falls back to the flat list provided by `source.getPages()`.

> [!NOTE]
> The order of pages in the EPUB is dictated by the site's navigation tree structure. If a page is not part of the tree, it is relegated to the fallback logic, which may not maintain the intended sequence.

Sources: [packages/epub/src/index.ts:92-99](https://github.com/blade47/fumadocs/blob/main/packages/epub/src/index.ts#L92-L99), [packages/epub/src/toc-builder.ts:5-25](https://github.com/blade47/fumadocs/blob/main/packages/epub/src/toc-builder.ts#L5-L25)

## Markdown to HTML Transformation

The transformation pipeline is handled by `markdownToHtml`, which uses a `unified` processor to sanitize and convert raw MDX content. A custom remark plugin `remarkResolveImg` is injected into the pipeline. This plugin visits all `image` nodes in the Markdown AST, invoking `resolveImageSrc` to convert local or relative path references into absolute URLs or `file://` URIs, ensuring that images within the EPUB display correctly regardless of the reader's environment.

Sources: [packages/epub/src/markdown-to-html.ts:10-37](https://github.com/blade47/fumadocs/blob/main/packages/epub/src/markdown-to-html.ts#L10-L37)

## CLI and Scaffolding

The CLI command `export-epub` manages the lifecycle of the generation process, especially for frameworks like Next.js that do not generate static files. It includes a scaffolding feature that creates a dedicated API route (`/export/epub/route.ts`) within the user's project, protected by an `EXPORT_SECRET`.

| Feature | Next.js Implementation | Other Frameworks |
| :--- | :--- | :--- |
| **Generation** | Fetches via API route | Copies from predefined path |
| **Route** | Scaffolded at `app/export/epub/route.ts` | Not required |
| **Auth** | Required `EXPORT_SECRET` | Depends on CI environment |

Sources: [packages/cli/src/commands/export-epub.ts:27-169](https://github.com/blade47/fumadocs/blob/main/packages/cli/src/commands/export-epub.ts#L27-L169)

## Image Path Resolution

The exporter implements robust logic to resolve cover images and embedded images. `resolveCoverPath` distinguishes between remote URLs, absolute paths in the `public` directory, and relative paths based on the current working directory (`cwd`). By mapping paths to file URLs, the exporter guarantees that `epub-gen-memory` can successfully pull the resources into the archive.

> [!CAUTION]
> If a file is not found, the image resolution logic will splice the image node out of the document entirely during the remark processing phase, preventing broken image placeholders in the final EPUB.

Sources: [packages/epub/src/index.ts:26-39](https://github.com/blade47/fumadocs/blob/main/packages/epub/src/index.ts#L26-L39), [packages/epub/src/markdown-to-html.ts:32-34](https://github.com/blade47/fumadocs/blob/main/packages/epub/src/markdown-to-html.ts#L32-L34)

## EPUB Configuration Logic

The `epubOptions` struct maps internal options to the generator's format. A critical design decision is the use of `prependChapterTitles: true` and `numberChaptersInTOC: true`. These are enabled by default because Fumadocs content often relies on existing heading hierarchy, and forcing these titles into the EPUB's explicit TOC facilitates easier navigation in standard e-readers that might not interpret nested HTML structure as deeply as a web browser.

Sources: [packages/epub/src/index.ts:124-135](https://github.com/blade47/fumadocs/blob/main/packages/epub/src/index.ts#L124-L135)

## Related

- [Command Line Interface](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/developer-tools/command-line-interface)


## Sitemap

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