|
| 1 | +# ADR-0001: Choose Documentation Framework |
| 2 | + |
| 3 | +## Status |
| 4 | + |
| 5 | +Accepted |
| 6 | + |
| 7 | +## Context |
| 8 | + |
| 9 | +`@pleaseai/code-style` monorepo needs a documentation site to describe the usage of its packages (`eslint-config`, `prettier-config`, `editorconfig`). The site will be deployed to **Cloudflare Pages**. |
| 10 | + |
| 11 | +### Constraints |
| 12 | + |
| 13 | +- **Package manager**: Bun (>=1.3.10) with workspace hoisting |
| 14 | +- **Module system**: ESM only |
| 15 | +- **Deployment**: Cloudflare Pages (static or SSR) |
| 16 | +- **Content**: Markdown-based, code examples, package configuration tables |
| 17 | + |
| 18 | +### Problem |
| 19 | + |
| 20 | +An initial attempt with **Docus** (Nuxt-based) failed in the build step. Bun stores dependencies under `node_modules/.bun/` symlinks. Nitro's built-in esbuild Rollup plugin excludes `node_modules/` from TypeScript transformation, but `@rollup/plugin-inject` still processes those files. Since Docus ships raw `.ts` server files (as a Nuxt layer), the inject plugin fails to parse TypeScript syntax. This is a known issue specific to Bun workspace setups. |
| 21 | + |
| 22 | +## Decision |
| 23 | + |
| 24 | +Use **Docus** (Nuxt-based) with docs excluded from Bun workspaces (independent `node_modules`). |
| 25 | + |
| 26 | +The Bun workspace build issue (Nitro's esbuild excludes `node_modules/`, causing `@rollup/plugin-inject` to fail on Docus's raw `.ts` files) is resolved by keeping docs as a standalone project with its own dependency tree. MCP toolkit is disabled (`mcp: { enabled: false }`) to avoid the `agents/mcp` Cloudflare Workers import issue. Content database uses SQLite locally and D1 conditionally via `NUXT_CONTENT_DATABASE_TYPE` env var. |
| 27 | + |
| 28 | +## Options |
| 29 | + |
| 30 | +| Criteria | Docus | VitePress | Starlight | Fumadocs | Nextra | |
| 31 | +|---|---|---|---|---|---| |
| 32 | +| **Framework** | Nuxt 4 | Vite + Vue | Astro | Next.js | Next.js | |
| 33 | +| **CF Pages** | SSR (D1 required) | SSG (official guide) | SSG (official adapter) | SSG (static export) | SSG (static export) | |
| 34 | +| **Bun compat** | Broken (inject + .ts) | Excellent | Good | Good | Good | |
| 35 | +| **Monorepo** | Poor (Bun symlinks) | Excellent | Good | Good | Good | |
| 36 | +| **Setup** | Medium | Low | Low | Medium | Low-Medium | |
| 37 | +| **Content** | Markdown + MDC | Markdown + Vue | Markdown + MDX | MDX | MDX | |
| 38 | +| **Search** | Built-in | Pagefind / Algolia | Pagefind (built-in) | Orama (built-in) | Flexsearch | |
| 39 | +| **i18n** | Plugin | Plugin | 30+ languages | Built-in | Limited | |
| 40 | +| **Dark mode** | Yes | Yes | Yes | Yes | Yes | |
| 41 | +| **GitHub stars** | ~3k | ~14k | ~7.7k | ~10.9k | ~12k | |
| 42 | + |
| 43 | +### Option 1: VitePress |
| 44 | + |
| 45 | +Vite-based, Vue-powered static site generator optimized for documentation. |
| 46 | + |
| 47 | +**Pros:** |
| 48 | +- Simplest setup, lowest overhead |
| 49 | +- Official Cloudflare Pages deployment guide |
| 50 | +- Excellent Bun and monorepo compatibility |
| 51 | +- Largest community (14k stars), battle-tested |
| 52 | +- Extremely fast (Vite-based, lightweight output) |
| 53 | + |
| 54 | +**Cons:** |
| 55 | +- Vue-centric (this repo is framework-agnostic) |
| 56 | +- i18n requires third-party plugin |
| 57 | +- Markdown only (no MDX) |
| 58 | + |
| 59 | +### Option 2: Starlight (Astro) |
| 60 | + |
| 61 | +Astro-based documentation framework with batteries included. |
| 62 | + |
| 63 | +**Pros:** |
| 64 | +- SSG mode works cleanly on Cloudflare Pages |
| 65 | +- Built-in Pagefind search, 30+ language i18n |
| 66 | +- Bun + CF Pages verified by community |
| 67 | +- Framework-agnostic (fits this repo's nature) |
| 68 | +- Accessible typography, good defaults |
| 69 | + |
| 70 | +**Cons:** |
| 71 | +- Astro is an additional framework to learn |
| 72 | +- Smaller plugin ecosystem than VitePress |
| 73 | + |
| 74 | +### Option 3: Fumadocs |
| 75 | + |
| 76 | +React/Next.js documentation framework with composable architecture. |
| 77 | + |
| 78 | +**Pros:** |
| 79 | +- Modern App Router, composable (Content -> Core -> UI) |
| 80 | +- Built-in OpenAPI and TypeScript Twoslash |
| 81 | +- Active development (10.9k stars) |
| 82 | +- MDX support |
| 83 | + |
| 84 | +**Cons:** |
| 85 | +- Next.js dependency (heavy for a simple docs site) |
| 86 | +- CF Pages requires `@cloudflare/next-on-pages` adapter |
| 87 | +- `fumadocs-mdx` uses webpack (not Bun's bundler) |
| 88 | + |
| 89 | +### Option 4: Docus (with workaround) |
| 90 | + |
| 91 | +Keep the Nuxt-based Docus with a custom Rollup plugin to strip TypeScript from `.bun/` paths. |
| 92 | + |
| 93 | +**Pros:** |
| 94 | +- Already partially set up |
| 95 | +- Rich Nuxt UI components, Nuxt Content integration |
| 96 | +- Consistent with `ask` repo's Nuxt ecosystem |
| 97 | + |
| 98 | +**Cons:** |
| 99 | +- Requires custom Rollup plugin workaround for Bun |
| 100 | +- `defineAppConfig` prerender issue (additional fix needed) |
| 101 | +- D1 database required for SSR on Cloudflare |
| 102 | +- Fragile — Docus/Nitro updates may break the workaround |
| 103 | + |
| 104 | +### Option 5: Nextra |
| 105 | + |
| 106 | +Next.js documentation framework (MDX-based). |
| 107 | + |
| 108 | +**Pros:** |
| 109 | +- Simple setup, mature (12k stars) |
| 110 | +- MDX + React components |
| 111 | + |
| 112 | +**Cons:** |
| 113 | +- Next.js dependency |
| 114 | +- Similar CF Pages adapter concerns as Fumadocs |
| 115 | +- Less actively developed than alternatives |
| 116 | + |
| 117 | +## Recommendation |
| 118 | + |
| 119 | +**Starlight** or **VitePress** are the strongest fits for this project: |
| 120 | + |
| 121 | +- **Starlight** if we value built-in i18n, search, and framework-agnostic identity |
| 122 | +- **VitePress** if we value simplicity, speed, and the largest community |
| 123 | + |
| 124 | +Both have proven Bun compatibility, clean SSG output for Cloudflare Pages, and minimal setup overhead. Neither requires database integration or custom workarounds. |
| 125 | + |
| 126 | +**Avoid Docus** until the Bun workspace + `rollup-plugin-inject` issue is resolved upstream. |
| 127 | + |
| 128 | +## Consequences |
| 129 | + |
| 130 | +### If Starlight is chosen |
| 131 | + |
| 132 | +- Add `docs/` as Astro project with `@astrojs/starlight` |
| 133 | +- Markdown content migrates directly (minor frontmatter adjustments) |
| 134 | +- Deploy via `astro build` -> `.output/` to CF Pages |
| 135 | + |
| 136 | +### If VitePress is chosen |
| 137 | + |
| 138 | +- Add `docs/` as VitePress project |
| 139 | +- Markdown content migrates directly |
| 140 | +- Deploy via `vitepress build` -> `.vitepress/dist/` to CF Pages |
| 141 | + |
| 142 | +### Neutral |
| 143 | + |
| 144 | +- Existing content (5 pages) can be reused with minor format changes regardless of choice |
| 145 | +- No impact on existing packages or monorepo build pipeline |
| 146 | + |
| 147 | +## References |
| 148 | + |
| 149 | +- [VitePress on Cloudflare Pages](https://developers.cloudflare.com/pages/framework-guides/deploy-a-vitepress-site/) |
| 150 | +- [Astro on Cloudflare](https://docs.astro.build/en/guides/deploy/cloudflare/) |
| 151 | +- [Starlight docs](https://starlight.astro.build/) |
| 152 | +- [Fumadocs static export](https://fumadocs.dev/docs/ui/static-export) |
| 153 | +- [Docus rollup-plugin-inject issue](https://www.answeroverflow.com/m/1434205777073147914) |
0 commit comments