nookdocs migrate is the one real command today. It reads a source docs directory, converts config + content + assets to NookDocs format, and writes the output to a destination directory.
Usage
nookdocs migrate <source-dir> [-o <output>] [--from <platform>] [--dry-run]Minimal:
nookdocs migrate ./my-docsAll flags:
nookdocs migrate ./my-docs \
--from mintlify \
--output ./nookdocs-migration \
--dry-runFlags
<source-dir>stringpathrequiredPath (relative or absolute) to the source docs directory. Must exist. The CLI reads files from here and never modifies them.
--from <platform>'mintlify' | 'docusaurus' | 'gitbook' | 'nextra' | 'fumadocs'pathForce a specific source platform. Skip to auto-detect. Useful when detection ambiguates (e.g. a repo has both docusaurus.config.ts and a leftover mint.json).
-o, --output <dir>stringpathdefault: ./nookdocs-outputDestination directory. Created if missing. Overwrites files on second run — git status diffs reveal what changed between runs.
--dry-runflagpathdefault: falseSkip file writes. The CLI still runs the full transform pipeline and prints the report (warnings, stats, errors) so you can audit what WOULD happen without touching disk.
-h, --helpflagpathPrint usage and exit. Works at command level (nookdocs --help) or subcommand level (nookdocs migrate --help).
Platform detection
When --from is omitted, the CLI probes well-known marker files in <source-dir>:
| Marker file | Platform detected |
docs.json with $schema: ".../mintlify/..." | mintlify |
docs.json with navigation + (colors or name) | mintlify (legacy, no $schema) |
mint.json | mintlify (legacy file name) |
docusaurus.config.js or docusaurus.config.ts | docusaurus |
.gitbook.yaml | gitbook |
theme.config.tsx or theme.config.jsx | nextra |
source.config.ts | fumadocs |
Today mintlify and docusaurus are implemented. If auto-detection returns GitBook / Nextra / Fumadocs, the CLI exits with an "unsupported platform" error — those migrators are planned (detection already scaffolded so activation is a drop-in).
What happens
Per platform, the migrator runs three passes against <source-dir>:
Config transform
Reads the source platform's config (docs.json, mint.json) and emits <output>/nookdocs.config.json with the canonical flat layout (contentRoot: "/", theme: "larch"). Navigation, colors, logo, navbar, footer, global anchors, and the OpenAPI binding all map over. Unmapped fields are listed under Manual review needed but don't block the run.
Content transform
Walks every .mdx / .md file and writes them flat to the output root. Most Mintlify components share NookDocs' tag names and pass through untouched; genuinely-renamed ones (<Latex>→<Math>, <Tree>→<FileTree>) are rewritten, and each rewrite is listed under Transforms applied in the report. Components with no NookDocs equivalent pass through verbatim; snippet imports are flagged for manual review.
Asset copy
Copies images, PDFs, and public assets to matching paths in the output directory so relative links keep resolving. Skips source node_modules/, .git/, .next/.
Report output
Every run — dry or real — prints a structured report at the end:
Migration complete! (mintlify → NookDocs)
Source: ./my-mintlify-docs
Output: ./nookdocs-output
✓ Config: docs.json → nookdocs.config.json
✓ Pages: 18 files converted
✓ Assets: 2 dirs (5 files), 1 file
✓ OpenAPI: api-reference/openapi.json → api-reference/openapi.json
Transforms applied:
essentials/markdown.mdx: <Latex> → <Math>
Manual review needed:
! contextual config not migrated — set contextual options if needed.
! essentials/reusable-snippets.mdx: snippet import detected — review manuallyTransforms applied lists components the migrator renamed. Manual review needed flags config keys with no direct equivalent and snippet imports — not errors, but check each before committing the output. On --dry-run the header is prefixed with DRY RUN.
Exit codes
0— migration completed (may include warnings, no errors)1— migration failed: missing source directory, unsupported platform, transform crash
CI pipelines should gate on exit code and review the report's Manual review needed section before committing the output.
Idempotency
Running the command twice on the same source produces byte-identical output (assuming source unchanged). Running on top of an existing output directory overwrites files without prompting — use git status to inspect the diff before committing.
Related
Overview — what the CLI is for
Install — Node.js requirements + global install
Migrating from Mintlify — detailed walkthrough
Migrating from Docusaurus — sidebars, admonitions, static assets