{"id":50392303,"url":"https://github.com/sitapix/mkdocs-material-to-starlight","last_synced_at":"2026-06-16T10:00:45.211Z","repository":{"id":356230657,"uuid":"1231403698","full_name":"sitapix/mkdocs-material-to-starlight","owner":"sitapix","description":"Convert MkDocs Material sites to Astro Starlight quickly","archived":false,"fork":false,"pushed_at":"2026-05-07T06:01:59.000Z","size":1160,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-07T07:41:14.651Z","etag":null,"topics":["astro","astro-starlight","docs-as-code","documentation-generator","markdown","material-for-mkdocs","mdx","migration","mkdocs","mkdocs-material","starlight","static-site-generator"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/mkdocs-material-to-starlight","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sitapix.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-06T23:43:20.000Z","updated_at":"2026-05-07T06:05:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sitapix/mkdocs-material-to-starlight","commit_stats":null,"previous_names":["sitapix/mkdocs-material-to-starlight"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/sitapix/mkdocs-material-to-starlight","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sitapix%2Fmkdocs-material-to-starlight","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sitapix%2Fmkdocs-material-to-starlight/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sitapix%2Fmkdocs-material-to-starlight/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sitapix%2Fmkdocs-material-to-starlight/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sitapix","download_url":"https://codeload.github.com/sitapix/mkdocs-material-to-starlight/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sitapix%2Fmkdocs-material-to-starlight/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34400456,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-16T02:00:06.860Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["astro","astro-starlight","docs-as-code","documentation-generator","markdown","material-for-mkdocs","mdx","migration","mkdocs","mkdocs-material","starlight","static-site-generator"],"created_at":"2026-05-30T19:00:25.380Z","updated_at":"2026-06-16T10:00:45.199Z","avatar_url":"https://github.com/sitapix.png","language":"TypeScript","funding_links":[],"categories":["Tools"],"sub_categories":["Customization"],"readme":"# mkdocs-material-to-starlight\n\n[![CI](https://github.com/sitapix/mkdocs-material-to-starlight/actions/workflows/ci.yml/badge.svg)](https://github.com/sitapix/mkdocs-material-to-starlight/actions/workflows/ci.yml)\n[![npm version](https://img.shields.io/npm/v/mkdocs-material-to-starlight.svg)](https://www.npmjs.com/package/mkdocs-material-to-starlight)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)\n[![Node](https://img.shields.io/node/v/mkdocs-material-to-starlight.svg)](./package.json)\n\n**Move your MkDocs Material site to Astro Starlight without rewriting pages by hand.**\n\nPoint one command at your `mkdocs.yml` and get a buildable Starlight project: pages converted, plugins mapped, sidebar wired up, redirects preserved, i18n intact. Anything the converter cannot handle lands in `MIGRATION_NOTES.md` with a file and line number.\n\n---\n\n## Quick start\n\n```bash\nnpx mkdocs-material-to-starlight\n```\n\nThe interactive wizard reads your `mkdocs.yml`, asks about the decisions that apply to your site, and writes a working Astro project. Then:\n\n```bash\ncd ./starlight-out\nnpm install\nnpm run dev\n```\n\nYour docs are live on Starlight. Requires Node 20+.\n\n\u003e **Preview the plan without writing files:**\n\u003e `npx mkdocs-material-to-starlight ./my-mkdocs --explain`\n\n---\n\n## Why use this\n\n- **Tested at real scale.** A first `--check` run typically takes 1–5 minutes; `astro check` is the slow step, not the converter. Repeat `--check` runs finish in 10–30s. Without `--check`, conversion alone finishes in seconds.\n- **Maps every Material feature.** Admonitions, tabs, grids, snippets, icons, math, mermaid, i18n, mike versions. Features without a clean Starlight equivalent (Jinja macros, custom theme overrides) become diagnostics with file and line numbers.\n- **Scripts cleanly.** The wizard prints its equivalent unattended command on exit. Drop that command into a CI workflow. Exit codes follow Unix convention.\n- **Idempotent.** Running it twice produces byte-identical output, so reruns do not churn diffs.\n\n---\n\n## What it converts\n\nIf MkDocs Material renders it, this tool maps it. The mapping by area:\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eMarkdown syntax and PyMdown extensions\u003c/strong\u003e\u003c/summary\u003e\n\n| MkDocs Material | Starlight output |\n|---|---|\n| `!!! note \"Title\"` admonitions (12 types) | `:::note[Title]` aside directives, type-mapped to Starlight's 4 |\n| `??? note` / `???+ note` collapsible | `\u003cdetails\u003e\u003csummary\u003eTitle\u003c/summary\u003e...\u003c/details\u003e` |\n| `=== \"Tab\"` content tabs | `\u003cdiv class=\"sl-tabs\"\u003e…\u003c/div\u003e` (with shim CSS) |\n| `\u003cdiv class=\"grid cards\" markdown\u003e` | `\u003cdiv class=\"sl-card-grid\"\u003e…\u003c/div\u003e` |\n| `\u003cdiv class=\"grid\" markdown\u003e` | `\u003cdiv class=\"sl-grid\"\u003e…\u003c/div\u003e` |\n| `:material-rocket:` / `:fontawesome-brands-github:` | `:icon[rocket]` / `:icon[github]`, with curated name mapping plus SVG fallback |\n| `--8\u003c-- \"snippet.md\"` | Inlines snippet content (with cycle detection and depth limit) |\n| `==text==` highlights | `\u003cmark\u003etext\u003c/mark\u003e` |\n| `H~2~O` subscripts and `2^10^` superscripts | `\u003csub\u003e` and `\u003csup\u003e` |\n| `++ctrl+alt+del++` keyboard keys | `\u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eAlt\u003c/kbd\u003e+\u003ckbd\u003eDel\u003c/kbd\u003e` |\n| `[link](api/auth.md)` internal refs | Rewritten to Starlight slugs (`[link](/api/auth)`) |\n| Footnotes (`[^1]`) | GFM footnotes via remark-gfm |\n| Math (`$inline$`, `$$block$$`) | remark-math plus rehype-katex (deps included) |\n| ` ```mermaid ` blocks | astro-mermaid (dep included) |\n| MagicLink autolinks (`@user`, `#123`) | Markdown links pointing at GitHub from `repo_url` |\n| Definition lists, abbreviations, buttons, CriticMarkup, code annotations | Normalized to standard Markdown or styled HTML |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eSite config and navigation\u003c/strong\u003e\u003c/summary\u003e\n\n| MkDocs | Starlight output |\n|---|---|\n| `nav:` tree | `sidebar` config in `astro.config.mjs` |\n| `site_name`, `site_description`, `site_url` | `title`, `description` on the integration; `site` on Astro config |\n| Missing frontmatter `title` | Synthesized from first H1 or humanized filename (Starlight requires it) |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003ePlugins\u003c/strong\u003e\u003c/summary\u003e\n\n| MkDocs plugin | Starlight output |\n|---|---|\n| `mkdocs-redirects` | `redirects: { … }` in `astro.config.mjs` |\n| `mkdocs-static-i18n` | Directory-prefix layout (`fr/page.md`) plus `locales: { … }` |\n| `mkdocs-section-index` | Section `index.md` hoisted to first child of its sidebar group |\n| `mkdocs-literate-nav` | `SUMMARY.md` parsed and used as the nav source |\n| `mkdocs-include-markdown-plugin` | `{% include %}` resolved inline before conversion |\n| `mkdocs-rss-plugin` | `@astrojs/rss` dep plus `src/pages/rss.xml.ts` scaffold |\n| `mkdocs-glightbox` | `starlight-image-zoom` dep |\n| `mike` (versioned docs) | `starlight-versions` dep |\n| `mkdocs-git-revision-date-localized` | Built-in `lastUpdated: true` |\n| `blog`, `tags` (Material) | `starlight-blog`, `starlight-tags` deps |\n| `mkdocs-macros-plugin` (Jinja2) | Per-occurrence diagnostic with file:line locator (cannot be evaluated) |\n| `gen-files`, `print-site`, `monorepo`, `multirepo`, `social`, `meta`, `privacy`, `mkdocstrings`, `mkdocs-jupyter` | Diagnostic in `MIGRATION_NOTES.md` with documented workaround |\n\n\u003c/details\u003e\n\n---\n\n## What you get\n\n```\noutput/\n├── astro.config.mjs              ← migrated config: sidebar, redirects, locales\n├── package.json                  ← scripts and pinned deps for every feature you used\n├── MIGRATION_NOTES.md            ← human-readable diagnostics, grouped by rule\n├── public/                       ← non-Markdown assets (images, PDFs) copied through\n└── src/\n    ├── content/docs/             ← every Markdown page, converted\n    └── styles/mkdocs-migration.css  ← shim so grids, cards, and tabs render correctly\n```\n\nThe project builds as-is for the common case. `cd output \u0026\u0026 npm install \u0026\u0026 npm run dev` and you have a running Starlight site.\n\n---\n\n## Common workflows\n\n```bash\n# First-time conversion: interactive wizard (recommended)\nnpx mkdocs-material-to-starlight\n\n# Unattended (CI or scripted): accepts the wizard's defaults\nnpx mkdocs-material-to-starlight ./mkdocs-project ./starlight-out --yes\n\n# Dry-run: print the migration plan, write nothing\nnpx mkdocs-material-to-starlight ./mkdocs-project --explain\n\n# Run with astro check so type and link errors fail fast\nnpx mkdocs-material-to-starlight ./mkdocs-project ./starlight-out --yes --check\n\n# Resolve PyMdown snippets from a custom directory\nnpx mkdocs-material-to-starlight ./mkdocs-project ./starlight-out \\\n  --yes --snippet-base-path docs --snippet-base-path includes\n```\n\nThe wizard prints the equivalent unattended command when it finishes, ready to paste into CI.\n\n---\n\n## Diagnostics\n\nThe converter does not throw on bad input. Anything it cannot handle becomes a typed diagnostic on the run report. A malformed admonition will not abort a 2,000-page conversion.\n\nIn your terminal:\n\n```\napi/auth.md:12:4  warning  broken-link  link target \"missing.md\" was not found in the slug map\n```\n\nIn `outputDir/MIGRATION_NOTES.md`:\n\n- A per-rule breakdown of every diagnostic, grouped by file\n- Any unmapped `mkdocs.yml` top-level fields you may want to migrate by hand\n- Workaround pointers for plugins that have no clean Starlight equivalent\n\nEvery rule is documented. `--explain` prints the registered description and fix for each one before you run a conversion.\n\n---\n\n## CLI reference\n\n```\nmkdocs-material-to-starlight \u003cproject-dir\u003e \u003coutput-dir\u003e [options]\nmkdocs-material-to-starlight \u003cproject-dir\u003e --explain\nmkdocs-material-to-starlight compare \u003cbaseline-url\u003e \u003cconverted-url\u003e [options]\n\nConvert options:\n  --snippet-base-path \u003cpath\u003e   Resolve PyMdown snippets against this directory.\n                               Repeatable; first match wins.\n  --check                      After conversion, run `astro check` against the\n                               output and surface its diagnostics.\n  --check-timeout \u003cms\u003e         Override the astro-check timeout (default: 5min).\n  --dry-run                    Plan only, do not write files. (Not yet wired through.)\n  --yes                        Accept wizard defaults; skip interactive prompts.\n\nCompare options (visual diff between rendered MkDocs and Starlight pages):\n  --pages a,b,c                Comma-separated paths to diff (default: /).\n  --threshold 0.01             Mismatch ratio that still counts as a match.\n  --report file.md             Write the Markdown report to a file instead of stdout.\n\nCommon:\n  -h, --help                   Show help.\n  --version                    Print the version.\n```\n\nExit codes: `0` success, `1` runtime or check failure, `2` usage error.\n\nThe `compare` subcommand requires Playwright and pixelmatch as optional peers:\n\n```bash\nnpm install playwright pixelmatch pngjs\nnpx playwright install chromium\n```\n\nThese are optional. The converter itself does not depend on them.\n\n---\n\n## Programmatic API\n\n```ts\nimport { convertSiteFromDisk } from 'mkdocs-material-to-starlight';\n\nconst result = await convertSiteFromDisk({\n  projectDir: '/path/to/mkdocs-project',\n  outputDir: '/path/to/output',\n  snippetBasePaths: ['docs'], // optional; enables snippet expansion\n});\n\nif (!result.ok) {\n  console.error(`${result.error.code}: ${result.error.message}`);\n  process.exit(1);\n}\n\nfor (const tagged of result.value.diagnostics) {\n  console.log(`${tagged.sourcePath}: ${tagged.diagnostic.ruleId}: ${tagged.diagnostic.message}`);\n}\n```\n\nThe success result also exposes `astroConfigSource`, `packageJsonSource`, `migrationNotesSource`, and `sidebarSource` for inspection or custom write strategies.\n\n---\n\n## Limitations\n\nRead these before you commit the output:\n\n- **Theme palette and custom CSS or JS** (`theme.palette`, `overrides/`, `extra_css`, `extra_javascript`) land in `MIGRATION_NOTES.md` rather than getting auto-translated. Starlight's design system has a different structure from Material's, so you will want to re-pick colors against the Starlight theme.\n- **`mkdocs-macros-plugin` Jinja2 expressions** cannot be evaluated. Each `{{ … }}` and `{% … %}` site is reported with file and line so it can be replaced by hand.\n- **`mkdocs-section-index` and `mkdocs-literate-nav`** cover the common cases. Advanced patterns (per-directory recursive `SUMMARY.md`, implicit-index injection for entries not in `nav:`) are not yet implemented.\n- **`--dry-run`** is parsed but a no-op. Use `--explain` instead.\n\nRun `--explain` first to see which features in your site will trigger diagnostics.\n\n---\n\n## How it works\n\nBuilt on the [unified](https://unifiedjs.com) and [remark](https://github.com/remarkjs/remark) ecosystem. Four design pillars:\n\n- **Plugin-isolated.** Every transform owns a disjoint MDAST `(node-type, name)` namespace. Plugins are commutative; reordering them does not change output.\n- **Idempotent.** `convert(convert(x)) === convert(x)` byte-equal. Verified at unit, composed, file, site, and CLI levels.\n- **Diagnostic-first.** Failures attach typed diagnostics to the report. They never throw.\n- **Functional core, imperative shell.** Pure logic in `domain/` and `use-cases/`. All I/O lives behind ports in `infrastructure/`.\n\n```\nsrc/\n├── domain/         Pure types, value objects, ports (no I/O, no framework deps)\n├── use-cases/      Application orchestration; functional core\n├── infrastructure/ Adapters for file system, YAML, unified; the imperative shell\n└── interface/      CLI and programmatic API; the only place that wires concrete adapters\n```\n\nThe full working agreement and architectural rules live in [`CLAUDE.md`](./CLAUDE.md).\n\n---\n\n## Development\n\nRequires Node 20+.\n\n```bash\nnpm install\nnpm test                                      # full suite, runs in ~10s\nnpm run typecheck                             # tsc --noEmit\nnpm run build                                 # emit dist/\n\nnpx vitest run path/to/file.test.ts           # single test file\nnpx vitest run -t 'pattern matches subject'   # single test by title\n```\n\nEvery commit that introduces production code includes the failing test that motivated it. The idempotency property test runs the full pipeline twice on every fixture and asserts byte-equality of the second pass.\n\nBug reports, real-world fixtures, and PRs are welcome at [github.com/sitapix/mkdocs-material-to-starlight/issues](https://github.com/sitapix/mkdocs-material-to-starlight/issues). Sites that break the converter are the most valuable contribution.\n\n---\n\n## License\n\n[MIT](./LICENSE) © sitapix\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsitapix%2Fmkdocs-material-to-starlight","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsitapix%2Fmkdocs-material-to-starlight","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsitapix%2Fmkdocs-material-to-starlight/lists"}