A beautiful, fast documentation template that writes and updates itself. Powered by the Doxa AI agent, TanStack Start, React 19, Tailwind CSS v4, TypeScript, and MDX — your docs stay in sync with every PR, with zero human babysitting.
Doxa gives you a production-ready documentation site out of the box — with edge deployment, AI-powered chat, rich MDX components, and a polished reading experience.
Built on TanStack Start for full-stack React with SSR, deployable to Cloudflare Workers, Vercel, and Docker for any VPS or container host.
The Doxa agent is built specifically to generate and auto-update documentation for your projects with zero human intervention. Point it at a repo and it ships a complete, structured set of docs — then keeps them in sync as the code evolves.
It integrates natively with this template: generated pages drop straight into src/contents/docs/, use the registered MDX components, and respect your section layout and frontmatter conventions out of the box.
Two ways to run it, both keep your docs current on every PR:
- Doxa GitHub App (Coming very soon) — install once on your repo. Every new PR is reviewed by the agent, which opens a follow-up PR (or commit) updating the affected docs pages so
mainis never out of sync with shipped code. - Open-source CLI (Coming very soon) — run the same agent locally or in your own CI. Wire it into a GitHub Action, pre-merge hook, or scheduled job — same behavior, your infrastructure.
The result: docs that stay accurate by default, without anyone remembering to update them.
- MDX support — write Markdown with embedded React components
- Built-in components — Cards, Notes, Steps, Tabs, FileTree, and more
- Mermaid.js diagrams — flowcharts, sequence diagrams, and graphs
- LaTeX math — KaTeX-powered mathematical expressions
- Syntax highlighting — Prism-based with titles, line highlighting, and copy button
- Tables — GitHub-flavored Markdown tables with full styling
- Multi-level sidebar navigation with collapsible sections
- Auto-generated table of contents
- Content pagination (previous/next)
- Deep nesting support for complex doc structures
- Fuzzy search with term highlighting
- AI chat with docs — ask questions about your documentation using TanStack AI (supports Anthropic, OpenAI, Grok, and OpenRouter)
- TanStack Start — full-stack React with SSR and file-based routing
- React 19 with latest features
- Tailwind CSS v4 for styling
- TypeScript strict mode throughout
- Radix UI primitives for accessible components
- Light/dark mode with system auto-detection
- SEO-ready with dynamic meta tags, Open Graph, Twitter Cards, and generated sitemaps
- Google Tag Manager integration
- Cloudflare Workers — edge deployment with Wrangler
- Vercel — one-click deploy with pre-configured setup
- Docker — one-command VPS deployment with a minimal Node distroless image
- Optimized for edge and container runtime performance
- Node.js ^24.x
- pnpm ^10.25.0
git clone https://github.com/ipenywis/doxa.git
cd doxa
pnpm install
pnpm devVisit http://localhost:3000 to view your docs locally.
pnpm build
pnpm startpnpm deployvercel link
vercel env add VITE_SITE_URL
vercel env add AI_API_KEY
pnpm deploy:vercelVITE_SITE_URL should match your public docs URL so canonical tags, sitemap, robots, and social metadata use the correct host.
docker build \
--build-arg VITE_SITE_URL=https://docs.example.com \
-t doxa-docs .
docker run --rm -p 6000:3000 \
-e AI_API_KEY=your-provider-key \
doxa-docsOpen http://localhost:6000 after the container starts. The Docker image builds the app with Nitro's Node server preset and runs the generated .output/server/index.mjs server from a non-root distroless Node 24 runtime. The app listens on port 3000 inside the container; -p 6000:3000 exposes it on port 6000 on your machine or VPS. Pass public VITE_* values as build arguments, and pass secrets such as AI_API_KEY or DOXA_GITHUB_TOKEN only at runtime.
Production builds generate /sitemap.xml with TanStack Start. The build seeds sitemap pages from src/contents/settings/documents.json; the default Cloudflare build also prerenders those pages and crawls internal links so docs pages stay discoverable.
The sitemap host is inferred from environment variables in this order:
VITE_SITE_URL
DOXA_SITE_URL
SITE_URL
PUBLIC_SITE_URL
PUBLIC_URL
VERCEL_PROJECT_PRODUCTION_URL
VERCEL_URL
VERCEL_BRANCH_URL
CF_PAGES_URL
URL
DEPLOY_URL
DEPLOY_PRIME_URL
Set VITE_SITE_URL=https://docs.example.com explicitly in production when you want canonical URLs, social metadata, AI-native route URLs, and sitemap entries to share the same public host.
src/
components/
markdown/ # MDX components (Card, Note, Step, Mermaid, FileTree)
ui/ # UI components (Tabs, Accordion, Button, Pre)
contents/
docs/ # Documentation content (MDX files)
settings/ # Navigation config (documents.ts)
lib/
components.ts # Component registry for MDX
settings/
main.ts # Site settings, SEO, features
agent/
component-playbook.md # Component reference for Doxa CLI agent
All site settings live in src/settings/main.ts:
- Site name, URL, description, and keywords
- Company info and branding
- SEO (Open Graph, Twitter Cards)
- Feature toggles (right sidebar, table of contents, AI chat, scroll to top)
- Google Tag Manager
| Script | Description |
|---|---|
pnpm dev |
Start dev server (Cloudflare) |
pnpm dev:vercel |
Start dev server (Vercel) |
pnpm build |
Production build (Cloudflare) |
pnpm build:docker |
Production build for Docker / Node server |
pnpm build:vercel |
Production build (Vercel) |
pnpm start:docker |
Run the Docker-targeted Node server locally |
pnpm deploy |
Deploy to Cloudflare Workers |
pnpm deploy:vercel |
Deploy to Vercel |
pnpm generate:docs |
Regenerate navigation from folder structure |
pnpm lint |
Run ESLint |
pnpm format |
Format with Prettier |
Doxa ships a unified content access layer with pluggable adapters. The AI chat agent, route renderers, and AI-native endpoints (/llms.txt, /llms-full.txt) all read from a single contentStore — swap the underlying backend with one env var, no code changes.
Two adapters ship out of the box:
vite (default and recommended) |
github |
|
|---|---|---|
| Where content lives | src/contents/docs/ in this repo |
Separate GitHub repo |
| Update model | Redeploy to ship changes | Edits appear within cache TTL |
| Latency | Zero (bundled at build time) | GitHub API + TTL cache |
| External calls | None | GitHub REST API |
| Best for | Site + docs shipped together | Content team edits in GitHub web UI; docs decoupled from site repo |
-
Set
CONTENT_SOURCE=githubin your environment -
Set the required GitHub env vars:
DOXA_GITHUB_OWNER=your-org DOXA_GITHUB_REPO=your-docs-repo DOXA_GITHUB_BRANCH=main # optional, default "main" DOXA_GITHUB_BASE_PATH=src/contents/docs # optional, default "src/contents/docs" DOXA_GITHUB_TOKEN=ghp_xxx # required for private repos DOXA_GITHUB_CACHE_TTL=300 # optional, default 300 (seconds)
-
Redeploy. Content now streams from GitHub — doc edits appear on the site within
DOXA_GITHUB_CACHE_TTLwith no redeploy.
Creating a GitHub token:
- Public repos: no token needed (60 req/hr limit; set one anyway for 5,000/hr).
- Private repos: create a fine-grained PAT at github.com/settings/tokens?type=beta with Contents: Read-only permission on the docs repo.
- Implement the
ContentAdapterinterface fromsrc/lib/content/types.ts. - Add a case to the
resolveAdapter()switch insrc/settings/content.ts. - Add any needed env vars to
.env.example.
All consumers keep working unchanged — they only see the stable contentStore API.
Doxa exposes its documentation in the llms.txt format so external AI tools (ChatGPT, Claude, Cursor, MCP clients) can discover and cite content directly:
| Route | What |
|---|---|
/llms.txt |
Index of all pages with titles, URLs, descriptions |
/llms-full.txt |
Full corpus concatenated — paste into an LLM for Q&A |
Both are generated on-demand from contentStore, so they stay in sync regardless of adapter.
Contributions welcome.
- Fork the repository
- Create a feature branch
- Commit your changes
- Open a pull request
This project is licensed under the MIT License. See the LICENSE file for details.
Islem Maboud — @Ipenywis
Affiliated with CoderOne