My App

Fumadocs vs Nextra

Bake-off lendo o source de ambos. Quem entrega melhor pra humanos e pra agentes LLM.

Comparo as duas frameworks lendo o repositório de cada uma, não o marketing.

TL;DR

Fumadocs se você precisa que agentes LLM consumam suas docs ou se você não está casado com Next.js. Nextra se você é 100% Next.js, quer um tema polido por default, e ChatGPT/Claude jump-out fora-da-caixa.

Quem usar quando

Use Fumadocs se…

Você documenta um SDK / API que será scrapeado por agentes; quer `llms.txt` nativo; usa TanStack Start, React Router, Waku, Vite; precisa renderizar OpenAPI; quer i18n robusta.

Use Nextra se…

Tudo é Next.js App Router e vai continuar sendo; tempo até a primeira página importa mais que extensibilidade; o leitor é humano que vai abrir no ChatGPT/Claude manualmente.

Matriz

DimensãoFumadocsNextraVence
FrameworksNext, TanStack Start, React Router, Waku, ViteNext.js ≥14🟧 Fuma
llms.txt nativoSim (core/src/source/llms.ts, remark-llms)Não🟧 Fuma
Copy-as-Markdown UIMarkdownCopyButton em todos os layoutsCopyPage com ChatGPT/Claude deep-links⚖️ Empate
OpenAPI → MDXfumadocs-openapi@10.8 codegenNão em core🟧 Fuma
Fontes de conteúdoMDX, MD, content-collections, Obsidian, Sanity, BaseHub, Python, GitHub remoteMDX, GitHub remote🟧 Fuma
Subpath exports~50 paths em fumadocs-core (ESM only)4 paths em nextra🟧 Fuma
Tempo até primeira páginaMaior (escolher framework + UI + content)Menor (nextra + theme + go)🟦 Nextra
Tema default polido3 layouts (docs, notebook, flux) — precisa escolher1 tema, opinado, brilhante🟦 Nextra
Exemplos no repo254🟧 Fuma

Arquitetura

Headless + adapter por framework. fumadocs-core não sabe nada sobre Next — sabe sobre docs. Cada framework é um arquivo de adapter.

packages/core/src/framework/
  ├ next.tsx        ← Next.js adapter
  ├ react-router.tsx
  ├ tanstack.tsx
  └ waku.tsx

UI separada em base-ui (Tailwind puro) ou radix-ui (Tailwind + Radix). Você compõe.

Stack acoplada a Next.js App Router. O pacote nextra é o compilador + page-map; os temas (nextra-theme-docs, nextra-theme-blog) são opinions completas. Você instala, pluga next.config.mjs, e ganha um site.

packages/
  ├ nextra/              ← compile + page-map + loader
  ├ nextra-theme-docs/   ← single happy path
  └ nextra-theme-blog/

Quase nada pra decidir. Quase nada pra trocar.

LLM / Code-agent friendliness

Dois leitores hoje: humano e máquina. A framework decide quão bem a máquina come.

Score

CritérioPesoFumadocsNextra
llms.txt / flat-markdown endpoint25%104
Markdown raw alcançável por URL15%96
AI provider deep-link UI10%610
Subpath imports tipados pra code agents20%107
Page-map estável pra crawl15%89
Baixa carga cognitiva pra codegen15%79
Total ponderado9.07.0

Como cada uma alimenta o agente

agent  ─GET /llms-full.txt─►  site
agent  ◄─whole tree as markdown─  site
        (1 fetch, zero HTML noise)

/llms.txt/*path reescrito automaticamente a partir de /docs/*path.mdx (core/test/negotiation.test.ts:39). Markdown raw servido como rota de primeira classe.

agent  ─GET /docs/api/auth─►  site
agent  ◄─full HTML w/ theme chrome─  site
agent  strip nav · extract main · repeat

OU: humano clica Copy PageOpen in Claude → cola conteúdo. Funciona, mas o agente precisa do humano no meio.

Nuance

Nextra não impede llms.txt — só não vem pronto. Você escreve um route handler em app/llms.txt/route.ts que lê seu page-map e concatena os MDX. Custa ~30 linhas. Mas é seu problema, não da framework.

Gotchas reais (de quem deployou)

Conclusão pragmática

Recomendação

Padrão pra projetos novos onde docs servem humano + agente: Fumadocs. O custo extra de composição se paga no llms.txt nativo + OpenAPI + escape route de framework.

Padrão pra projetos onde docs servem humano dentro de uma stack 100% Next: Nextra. Você ganha o tempo de volta no tema default e perde pouco (llms.txt é 30 linhas de route handler).

Source lido

Repositórios clonados via opensrc, lidos diretamente:

  • github.com/fuma-nama/fumadocs@dev
    • packages/core/package.json (v16.8.11)
    • packages/core/src/source/llms.ts:101,107
    • packages/core/src/mdx-plugins/remark-llms.ts:58
    • packages/core/test/negotiation.test.ts:39-47
    • packages/core/src/framework/{next,tanstack,react-router,waku}.tsx
    • packages/{base-ui,radix-ui}/src/layouts/shared/page-actions.tsx:59
    • packages/openapi/package.json (v10.8.5)
  • github.com/shuding/nextra@main
    • packages/nextra/package.json (v4.6.4 · "next": ">=14")
    • packages/nextra-theme-docs/src/components/copy-page.tsx
    • packages/nextra-theme-docs/src/mdx-components/wrapper.client.tsx:47-48
    • packages/nextra/src/server/{compile,page-map,locales}

On this page