Getting started
This guide starts with an empty project and ends with a deployable static site in dist.
1. Check the build environment
Doctrine requires Node.js 20.19 or newer and a
native target supported by @amamo/mdx. The native
compiler has no JavaScript fallback. MDX can execute JavaScript during bundling, prerendering, and
hydration, so use content and configuration from trusted authors only.
Install the package:
pnpm add @amamo/doctrinenpm install @amamo/doctrineyarn add @amamo/doctrinebun add @amamo/doctrineThen create the content directory:
mkdir -p docs/guide2. Add two pages
Create docs/index.mdx:
# My project documentation
Choose a guide from the navigation.Create docs/guide/install.mdx:
# Install My project
<InstallTabs packageName="my-project" />Neither page needs frontmatter. An optional string description becomes that page's meta
description.
3. Define the navigation
Each directory with MDX for a locale needs the matching navigation module. The root docs/meta.ts
orders the home page and child directory:
import { defineDirectory } from '@amamo/doctrine'
export default defineDirectory({
items: [{ page: 'index', title: 'My project documentation' }, { directory: 'guide' }],
})Create docs/guide/meta.ts beside the nested page:
import { defineDirectory } from '@amamo/doctrine'
export default defineDirectory({
title: 'Guide',
items: [{ page: 'install', title: 'Install My project' }],
})The array controls exact sidebar order. page names a direct MDX basename; directory names a
direct child. The production build requires every page and child directory exactly once.
4. Start development
doctrine dev docsOpen http://localhost:5173. Vite server-renders each request and hydrates it in the browser. MDX
changes update through the content plugin; adding, removing, or editing navigation metadata refreshes
the route model without restarting the server.
Development tolerates a brief mismatch while a page and its meta.ts entry are saved separately.
The Pagefind development index is invalidated by content changes and rebuilt lazily on the next
search request.
Choose another interface or port when needed:
doctrine dev docs --host 0.0.0.0 --port 41735. Add optional site metadata
Create doctrine.config.ts in the directory where the CLI runs:
import { defineConfig } from '@amamo/doctrine'
export default defineConfig({
title: 'My project documentation',
description: 'Product guides and API notes for My project.',
githubUrl: 'https://github.com/your-org/my-project',
})Without a config file, the title is Documentation, the description is
Documentation built from MDX., and en is the only locale.
6. Build the static site
Pass the real public URL, including any repository pathname:
doctrine build docs --site-url https://docs.example.com/The default output is:
dist/
├── 404.html
├── assets/
├── guide/install.md
├── guide/install/index.html
├── index.html
├── index.md
└── pagefind/Doctrine builds client and SSR bundles, prerenders every navigation route, writes the authored MDX
at the matching .md paths, removes Vite's private manifest, and indexes the resulting HTML with
Pagefind. A repository URL such as
https://user.github.io/my-project/ changes public URLs to /my-project/...; it does not create
dist/my-project.
7. Keep generated work out of Git
In addition to dist, Doctrine uses .amamo-mdx/ for the generated content registry and cache
records, and .doctrine/ for temporary build work. Add all three to the project's ignore file.
Continue with Configuration for every option, Customization for styling and overrides, MDX components for built-ins, or GitHub Pages for a deployment workflow.