Developer-first documentation stack with diagrams-as-code
A two-service monorepo combining Fumadocs v15 (Next.js) for beautiful MDX documentation with Kroki for rendering diagrams from code. Built for developer experience with one-command setup and hot reload in Docker.
- 🎨 Dark/Light Theme Support - All diagrams adapt automatically
- 🔍 Zoomable Diagrams - Click any diagram to open in fullscreen with pan/zoom
- 🚀 Hot Reload - Edit MDX or components, see changes instantly
- 🔒 Secure by Default - Path traversal protection, size limits, language allowlist
- 📦 One Command -
./scripts/dev.shstarts everything or if you have Node.js installed you can runpnpm dev - 🎯 Type-Safe - TypeScript strict mode throughout
- Node.js 22 with pnpm
- Next.js 15 App Router
- Fumadocs v15 for documentation UI
- Kroki for diagram rendering
- Mermaid for inline diagrams
- React Flow for zoomable viewer
- TailwindCSS 3 for styling
- Docker & Docker Compose for containerization
- Node.js 22+
- pnpm 9+
- Docker & Docker Compose v2
# Clone the repository
git clone https://github.com/wallwhite/hyperion-docs.git
# Navigate to the project directory
cd hyperion-docs
# Install dependencies
pnpm install
# Start both services (docs + kroki)
pnpm devVisit http://localhost:3000 - changes hot-reload automatically!
# Stop both services (docs + kroki)
pnpm stop
# or use the script
./scripts/stop.shdocker build . -f apps/docs/Dockerfile.prod -t archipelagoIt will build production-optimized image with all dependencies installed.
docker run --env KROKI_BASE_URL=https://kroki.io -p 3000:3000 archipelagoNow you can see docs on http://localhost:3000.
Please note that you need to set KROKI_BASE_URL to your Kroki instance. Here we set it to https://kroki.io,
what is public instance of Kroki but it could be insecure or unavailable to use in your production.
hyperion-docs/
├── apps/
│ └── docs/ # Next.js + Fumadocs app
│ ├── app/ # Next.js App Router
│ │ ├── api/diagram/ # Diagram proxy API
│ │ ├── docs/ # Docs routes
│ │ ├── layout.tsx # Root layout
│ │ └── page.tsx # Home page
│ ├── components/ # React components
│ ├── content/docs/ # MDX documentation
│ ├── diagrams/ # Diagram source files (.puml, .dot)
│ ├── openapi/ # OpenAPI schema files (.yaml)
│ ├── lib/ # Utilities
│ ├── mdx-components.tsx # MDX component config
│ ├── source.config.ts # Fumadocs source config
│ └── Dockerfile # Docs service Dockerfile
├── docker-compose.yml # Services orchestration
├── pnpm-workspace.yaml # Monorepo config
└── package.json # Root scripts
<Diagram lang="mermaid" chart="
graph TD;
A[Client] --> B[Server];
B --> C[Database];" />Place your diagram files in apps/docs/diagrams/:
<Diagram lang="plantuml" path="erd.puml" alt="Entity Relationship Diagram" />
<Diagram lang="graphviz" path="flow.dot" alt="Processing Flow" />- PlantUML -
puml,plantuml - Graphviz -
dot,graphviz - Mermaid -
mermaid(or use<Mermaid>component) - C4 PlantUML -
c4plantuml
Easily extend by adding to LANG_MAP in apps/docs/app/api/diagram/route.ts.
MDX File → <Diagram> Component → /api/diagram API Route → Kroki Service → SVG/PNG Response
- Runtime:
nodejs(required forfsaccess) - Security: Path allowlist, size limits, language validation
- Caching:
Cache-Control: no-storein dev
Query Parameters:
lang- Diagram language (e.g.,puml,dot)path- Relative path to diagram filefmt- Output format (svgorpng, default:svg)
- Fetches from
/api/diagramor generates Mermaid diagrams directly from the chart string - Opens modal on click
- Supports SVG
- Whiteboard canvas
- Pan, zoom, reset controls
These variables configure API resources and static site generation behavior.
API_RES_PATH— Absolute or relative path to the API resources directory used by the docs app.- Example:
API_RES_PATH=openapi
- Example:
IS_PROD_STATIC— Enable production static export mode (trueorfalse).- Example:
IS_PROD_STATIC=true
- Example:
GITHUB_PAGES_REPO_NAME— Repository name used for GitHub Pages base path when static export is enabled.- Example:
GITHUB_PAGES_REPO_NAME=hyperion-docs
- Example:
cd apps/docs
pnpm install
pnpm devNote: You'll need to run Kroki separately or set
KROKI_BASE_URLto a public instance.
-
Add language mapping to
apps/docs/app/api/diagram/route.ts:const LANG_MAP: Record<string, string> = { // ...existing d2: 'd2', // Add new type };
-
Create diagram files in
apps/docs/diagrams/ -
Use in MDX:
<Diagram lang="d2" path="my-diagram.d2" />
Edit apps/docs/tailwind.config.ts to customize Tailwind or override Fumadocs styles.
- Path Traversal: All paths resolved relative to
apps/docs/diagramsand validated - File Size: Max 256 KB per diagram file
- Language Allowlist: Only mapped languages accepted
- No Code Execution: Diagrams treated as opaque text sent to Kroki
- Check Kroki is running
- Verify diagram file path is relative to
apps/docs/diagrams - Check browser console for API errors
- Confirm language is in
LANG_MAP
cd apps/docs
pnpm typecheckMIT
- Fork the repo
- Create a feature branch
- Make your changes
- Submit a pull request
Built with ❤️ using Fumadocs, Next.js, and Kroki