はじめに
技術ドキュメントを作るの、正直面倒くさいですよね。
Markdownで書いて、何らかの静的サイトジェネレーターで変換して、デプロイして...という流れは分かる。でも、サイドバーの設定とか、検索機能の実装とか、細かいところで時間を取られる。
GitBookやDocusaurusを使ってきたけど、カスタマイズしたいときに「ここ、もっと自由にいじりたいんだけどな」と思うことが多かった。
そんなときに見つけたのがFumadocs。GitHubで9,700スター以上、136人以上のコントリビューターが参加している。「The beautiful & flexible React.js docs framework」というキャッチコピーに惹かれて試してみました。
これ、意外と良いんですよ。
Fumadocsとは
FumadocsはReact.jsベースのドキュメントフレームワークです。
「あらゆるReact.jsフレームワークでドキュメントサイトを構築するためのフレームワーク」という説明が公式にありますが、要するに「React開発者が使いやすいように設計されたドキュメントツール」です。
Next.js、Tanstack Start、React Router、Wakuなど複数のフレームワークに対応。MITライセンスで、ESM(ECMAScript Modules)専用のモダンな設計になっています。
開発は活発で、最新コミットは数時間前。4,700以上のコミット数からも、継続的にメンテナンスされていることが分かります。
特徴・メリット
1. モジュラーアーキテクチャ
Fumadocsは4つのモジュールに分離されています。
- fumadocs-core: ヘッドレスライブラリ(コア機能)
- fumadocs-ui: UIコンポーネント
- fumadocs-mdx: MDXコンテンツ処理
- fumadocs-openapi: OpenAPIドキュメント拡張
必要なモジュールだけ使える。フル機能が欲しければ全部入れればいいし、UIだけ自作したければcoreだけ使えばいい。
この「選べる」感じ、個人的には好きです。
2. Next.jsとの親和性が高い
TypeScriptが75%以上を占めるコードベース。Next.jsのApp Routerにネイティブ対応していて、SSGにも完全対応。
普段Next.jsを使っている人なら、違和感なく導入できます。
3. MDX完全対応
MarkdownにReactコンポーネントを埋め込めるMDXをネイティブサポート。コードベースの21%がMDXで構成されているくらい、MDXを中心に設計されています。
技術者だけでなく、非エンジニアやAIエージェントでもコンテンツを作成しやすい設計になっています。
4. 美しいデフォルトUI
「Build excellent documentations, your style」がコンセプト。デフォルトのUIがかなり洗練されていて、そのまま使ってもプロフェッショナルに見える。
もちろんカスタマイズも自由。Tailwind CSSベースなので、細かい調整も簡単です。
5. 複数フレームワーク対応
Next.jsだけでなく、Vite系のTanstack Start、React Router、Wakuにも対応。プロジェクトの技術スタックに合わせて選べます。
インストール方法
最速でプロジェクト作成
pnpm create fumadocs-app
このコマンドを実行すると、対話形式でプロジェクト名とフレームワーク(Next.js、Tanstack Start、React Routerなど)を選択できます。
npmやyarnでも同様に使えます。
# npm
npx create-fumadocs-app
# yarn
yarn create fumadocs-app
既存プロジェクトへの追加
# 必要なパッケージをインストール
pnpm add fumadocs-ui fumadocs-core fumadocs-mdx
基本的な使い方
プロジェクト構成
my-docs/
├── app/
│ ├── layout.tsx
│ ├── page.tsx
│ └── docs/
│ └── [[...slug]]/
│ └── page.tsx
├── content/
│ └── docs/
│ ├── index.mdx
│ └── getting-started.mdx
├── source.config.ts
├── next.config.mjs
└── package.json
Next.jsのApp Routerを使った構成。content/docsにMDXファイルを置くだけでドキュメントページが生成されます。
source.config.ts(ソース設定)
import { defineDocs, defineConfig } from 'fumadocs-mdx/config';
export const { docs, meta } = defineDocs({
dir: 'content/docs',
});
export default defineConfig();
ドキュメントのソースディレクトリを定義します。シンプル。
ドキュメントページの実装
// app/docs/[[...slug]]/page.tsx
import { source } from '@/lib/source';
import {
DocsPage,
DocsBody,
DocsDescription,
DocsTitle,
} from 'fumadocs-ui/page';
import { notFound } from 'next/navigation';
import defaultMdxComponents from 'fumadocs-ui/mdx';
export default async function Page({
params,
}: {
params: { slug?: string[] };
}) {
const page = source.getPage(params.slug);
if (!page) notFound();
const MDX = page.data.body;
return (
<DocsPage toc={page.data.toc}>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
<DocsBody>
<MDX components={{ ...defaultMdxComponents }} />
</DocsBody>
</DocsPage>
);
}
export async function generateStaticParams() {
return source.generateParams();
}
export function generateMetadata({ params }: { params: { slug?: string[] } }) {
const page = source.getPage(params.slug);
if (!page) notFound();
return {
title: page.data.title,
description: page.data.description,
};
}
generateStaticParamsでSSG対応。ビルド時にすべてのページを静的生成できます。
MDXファイルの書き方
---
title: はじめに
description: Fumadocsの使い方を説明します
---
## 概要
Fumadocsは、React.jsベースのドキュメントフレームワークです。
<Callout type="info">
このように、MDX内でReactコンポーネントを使えます。
</Callout>
## インストール
```bash
pnpm create fumadocs-app
コード例もシンタックスハイライト付きで表示されます。
frontmatterでタイトルと説明を定義。本文はMarkdown + Reactコンポーネントで書けます。
### レイアウト設定
```typescript
// app/layout.tsx
import { RootProvider } from 'fumadocs-ui/provider';
import 'fumadocs-ui/style.css';
import type { ReactNode } from 'react';
export default function Layout({ children }: { children: ReactNode }) {
return (
<html lang="ja">
<body>
<RootProvider>{children}</RootProvider>
</body>
</html>
);
}
RootProviderでラップするだけ。グローバルスタイルもインポート一行で完了。
実践的なユースケース
サイドバーのカスタマイズ
// lib/source.ts
import { loader } from 'fumadocs-core/source';
import { createMDXSource } from 'fumadocs-mdx';
import { docs, meta } from '@/.source';
export const source = loader({
baseUrl: '/docs',
source: createMDXSource(docs, meta),
});
ファイル構造に基づいて自動的にサイドバーが生成されます。順序を変えたい場合はmeta.jsonで制御可能。
検索機能の実装
// app/api/search/route.ts
import { source } from '@/lib/source';
import { createSearchAPI } from 'fumadocs-core/search/server';
export const { GET } = createSearchAPI('advanced', {
indexes: source.getPages().map((page) => ({
title: page.data.title,
structuredData: page.data.structuredData,
url: page.url,
})),
});
数行で全文検索APIが完成。フロントエンドのSearchDialogコンポーネントと組み合わせれば、Cmd+Kで検索できるUIが実現します。
OpenAPIドキュメント統合
import { generateFiles } from 'fumadocs-openapi';
void generateFiles({
input: ['./openapi.yaml'],
output: './content/docs/api',
});
OpenAPI(Swagger)仕様書からドキュメントを自動生成。API仕様とドキュメントを一元管理できます。
ダークモード対応
// app/layout.tsx
import { RootProvider } from 'fumadocs-ui/provider';
export default function Layout({ children }) {
return (
<html lang="ja" suppressHydrationWarning>
<body>
<RootProvider
theme={{
enabled: true,
defaultTheme: 'system',
}}
>
{children}
</RootProvider>
</body>
</html>
);
}
テーマ切り替えもビルトイン。設定するだけでライト/ダークモードに対応。
他のドキュメントツールとの比較
30代になって思うのは、ツール選定って「何を優先するか」で決まるということ。
- Docusaurus: Facebookが作った定番。Reactベースだけど、カスタマイズの自由度はFumadocsより低め
- VitePress: Vue.jsベース。Vueユーザーには良いけど、Reactプロジェクトには不向き
- GitBook: SaaSで楽だけど、細かいカスタマイズには限界がある
- Fumadocs: Reactエコシステムにネイティブ統合。カスタマイズ性高め
個人的には、Next.jsプロジェクトのドキュメントを作るならFumadocs一択ですね。既存のReactコンポーネントをそのまま使えるのが大きい。
まとめ
Fumadocsを使ってみて感じたこと:
- セットアップ:
pnpm create fumadocs-appで即座に開始 - 学習コスト: Next.js/React知ってれば低い。MDXも直感的
- カスタマイズ性: モジュラー設計で必要な部分だけ差し替え可能
- デフォルトUI: そのまま使ってもプロフェッショナル
- 検索機能: ビルトインで全文検索対応
- SSG対応: 静的サイトとして高速配信
正直なところ、ドキュメントサイト構築って「必要だけど面倒な作業」だと思っていました。Fumadocsを使ってからは、「これ、意外と楽しいかも」と思えるようになった。
技術ドキュメントを整備したいけど後回しにしている人、OSSプロジェクトのドキュメントサイトを作りたい人、社内ナレッジベースを構築したい人。そういう人にFumadocsはおすすめです。
まずはpnpm create fumadocs-appを叩いてみてください。5分後にはきれいなドキュメントサイトの骨格ができています。
