Markdown converter (local, no server). Supports Mermaid/Graphviz/Vega/HTML/SVG rendering, math, and code highlighting.
npm install md2xMarkdown → PDF/DOCX/HTML/Image converter.

- 📦 Supported formats: pdf, docx, html, png, jpg/jpeg, webp
- 🔌 MCP (Model Context Protocol): built-in MCP server
- 🧠 Skills: includes an agent skill at skills/md2x/SKILL.md for repeatable conversions/workflows
- 🧩 Custom templates: render md2x blocks with Vue SFC (.vue) and Svelte 5 (.svelte) templates (plus plain HTML)
Export to PDF:
``bash`
npx md2x input.md
Export to DOCX:
`bash`
npx md2x input.md -f docx
Export to HTML:
`bash`
npx md2x input.md -f html
Export to PNG:
`bash`
npx md2x input.md -f png -o output.png
List themes:
`bash`
npx md2x --list-themes
Use a theme:
`bash`
npx md2x input.md -o output.pdf --theme academic
Help:
`bash`
npx md2x -h
| Option | Alias | Description | Default | Values |
|--------|-------|-------------|---------|--------|
| --help | -h | Show help message | - | - |--version
| | -v | Show version number | - | - |--output
| | -o | Output file path | Input name with format extension | File path |--format
| | -f | Output format | pdf | pdf, docx, html, png, jpg/jpeg, webp |--theme
| | -t | Theme name | default | See --list-themes |--diagram-mode
| | - | HTML/Image diagram rendering mode | live | img, live, none |--live-runtime
| | - | HTML live runtime injection strategy (only when diagramMode: live) | cdn | inline, cdn |--live-runtime-url
| | - | Custom runtime URL when --live-runtime cdn | - | URL |--hr-page-break
| | - | Convert horizontal rules to page breaks | true for PDF/DOCX, false for HTML/Image | true, false |--templates-dir
| | - | Extra template dir for md2x blocks (repeatable; resolved against input dir when relative) | - | Directory path |--list-themes
| | - | List all available themes | - | - |
- live (default): Render diagrams in the browser on load using the md2x live runtime (by default it is embedded into the output HTML; see liveRuntime below)img
- : Pre-render diagrams as embedded images (offline, stable; no CDN)none
- : Keep diagram source blocks only (no rendering)
When converting a markdown file, you can put options in YAML front matter (the CLI merges front matter with CLI flags; explicit CLI flags win).
`yaml`
---
format: pdf # pdf | docx | html | png | jpg | jpeg | webp
theme: default
hrAsPageBreak: true
---
`yaml`
---
format: pdf
title: "My Doc" # used for PDF metadata/header templates
pdf:
format: A4 # A4 | Letter | Legal | A3 | A5
landscape: false
margin:
top: 1cm
bottom: 1cm
left: 1cm
right: 1cm
printBackground: true
scale: 1
displayHeaderFooter: false
headerTemplate: ""
footerTemplate: "Page / "
---
`yaml`
---
format: docx
theme: default
hrAsPageBreak: true
---
`yaml`
---
format: html
title: "My Doc"
standalone: true # full HTML document (default)
baseTag: true # emit
diagramMode: live # img | live | none
liveRuntime: cdn # inline | cdn (default: cdn). Use "inline" for fully self-contained HTML.liveRuntimeUrl: "https://cdn.jsdelivr.net/npm/md2x@0.7.3/dist/renderer/" # chunked runtime base URL
cdn: # optional: override CDN URLs (used when diagramMode: live)
mermaid: "https://cdn.jsdelivr.net/npm/mermaid@11.12.2/dist/mermaid.min.js"
# Template blocks:
vue: "https://unpkg.com/vue@3/dist/vue.global.js"
vueSfcLoader: "https://cdn.jsdelivr.net/npm/vue3-sfc-loader/dist/vue3-sfc-loader.js"
svelteCompiler: "https://esm.sh/svelte@5/compiler"
svelteBase: "https://esm.sh/svelte@5/"
---
`yaml`
---
format: png
diagramMode: live # or "img" for offline (no CDN)
image:
# selector can be a string or an array of selectors (CSS selector list).
selector:
- 'div.md2x-diagram[data-md2x-diagram-kind="mermaid"]'
- 'div.md2x-diagram[data-md2x-diagram-kind="infographic"]'
# selectorMode: first | each | union | stitch (default: stitch)
# - union: capture the union bounding box (includes in-between page content)
# - stitch: stack matched elements and capture only them (no in-between content)
selectorMode: stitch
selectorGap: 16 # optional: vertical gap (px) between stitched elements
selectorPadding: 8 # optional: padding (px) around the stitched region
split: auto # optional: split very tall output into multiple images
---
When image.split produces multiple parts, outputs are written as output.part-001.png, output.part-002.png, ...
Diagram blocks are tagged with data-md2x-diagram-kind so you can target specific types via selectors:
`yaml`
image:
selector: 'div.md2x-diagram[data-md2x-diagram-kind="mermaid"]'
selectorMode: stitch
Besides diagram blocks (mermaid/dot/vega-lite/infographic), md2x also supports template blocks via:
``md`md2x`
{
type: 'vue', // "vue" | "html" | "svelte"
template: 'example.vue', // or "example.html" / "example.svelte"
data: [{ title: 't', message: 'm' }]
}``
`
//example.vue
{{ item.message }}Hello md2x! This is vue template
{{ item.title }}
`
`svelte
{item.message}
`
- type: "vue", "html", or "svelte" (Svelte 5)template
- : template file name/pathexample.vue
- if you only pass a filename (e.g. ), it is treated as ${type}/${template} (e.g. vue/example.vue)data
- : arbitrary JSON-serializable data (injected by replacing the templateData placeholder)allowTemplateAssets
- (optional, unsafe): when true, allow templates to load extra JS/CSS URLs declared in the template file header:
- window.dayjs
- Useful for UMD/IIFE globals (e.g. ), not npm-style import.allowCdn
- Backward compat: is accepted as an alias.allowScripts
- (optional, unsafe, html only): when exporting images in diagramMode: "img", set allowScripts: true to execute inline