Write in Markdown. Track in Git. Ship as PDF.
md2pdf is a CLI for turning the technical Markdown you already write — design docs, runbooks, security reports — into clean, deliverable PDFs (or Word/DOCX). Mermaid diagrams render as inline SVG. Japanese (and other CJK) text renders without font breakage. Single Go binary, drop-in for CI.
Output of examples/06-japanese-document: Japanese text and a colored Mermaid flowchart, both rendered cleanly.
- 📐 Mermaid diagrams as inline SVG — vector-clean, no rasterization
- 🇯🇵 Japanese / CJK text out of the box — Noto Sans CJK JP preconfigured
- 📝 GitHub-flavored Markdown — tables, fenced code blocks, strikethrough
- 📃 PDF or DOCX output —
-format docxexports editable Word documents (via pandoc) - 🤖 CI-friendly single binary —
go installand you're done - 📄 Configurable — page size, margins, fonts
Homebrew (macOS / Linux) — recommended
brew install 135yshr/tap/md2pdfGo install
go install github.com/135yshr/md2pdf/cmd/md2pdf@latestBuild from source
git clone https://github.com/135yshr/md2pdf.git
cd md2pdf
go build -o md2pdf ./cmd/md2pdfmd2pdf uses external tools for diagram rendering and PDF generation. Install them after installing md2pdf:
# Mermaid CLI (diagram rendering)
npm install -g @mermaid-js/mermaid-cli
# Playwright + Chromium (PDF generation)
pip install playwright
playwright install chromium
# pandoc — only needed for DOCX output (-format docx)
brew install pandoc # macOS / Linux (Homebrew)
# sudo apt install pandoc # Ubuntu / DebianFor Japanese text support, install the Noto Sans CJK JP font:
macOS
brew install font-noto-sans-cjkUbuntu / Debian
sudo apt install fonts-noto-cjkmd2pdf document.mdA document.pdf file will be generated in the same directory. To export Word
instead, run md2pdf -format docx document.md.
| Dependency | Purpose | Install |
|---|---|---|
| mmdc | Mermaid → SVG/PNG | npm install -g @mermaid-js/mermaid-cli |
| Python 3 + Playwright | HTML → PDF | pip install playwright && playwright install chromium |
| pandoc | HTML → DOCX (only for -format docx) |
brew install pandoc / apt install pandoc |
| Noto Sans CJK JP | Japanese font (optional) | See above |
| Go 1.26+ | Build from source only | https://go.dev |
md2pdf [options] <input.md>| Flag | Default | Description |
|---|---|---|
-o <path> |
<input>.pdf |
Output path (.docx extension implies -format docx) |
-format <fmt> |
pdf |
Output format: pdf or docx (inferred from -o extension when omitted) |
-font <path> |
auto-detected | Noto Sans CJK JP Regular font |
-font-bold <path> |
auto-detected | Noto Sans CJK JP Bold font |
-font-medium <path> |
auto-detected | Noto Sans CJK JP Medium font |
-mmdc <path> |
auto-detected | Path to mmdc binary |
-pandoc <path> |
auto-detected | Path to pandoc binary (used for -format docx) |
-docx-font <family> |
Yu Gothic |
Font family for DOCX output (Latin + East Asian) |
-python <path> |
auto-detected | Python 3 interpreter with playwright installed (env: MD2PDF_PYTHON) |
-puppeteer-config <f> |
auto-generated | Puppeteer JSON config for mmdc |
-page-size <size> |
A4 |
A4, Letter, or A3 |
-margin-top <m> |
18mm |
Top margin |
-margin-bottom <m> |
18mm |
Bottom margin |
-margin-left <m> |
14mm |
Left margin |
-margin-right <m> |
14mm |
Right margin |
-v |
false | Verbose output |
-version |
— | Print version and exit |
# Basic conversion
md2pdf document.md
# Custom output path
md2pdf -o report.pdf document.md
# Export to Word (DOCX)
md2pdf -format docx document.md
md2pdf -o report.docx document.md # format inferred from extension
# Explicit font path
md2pdf -font /usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc document.md
# Letter size with wider margins
md2pdf -page-size Letter -margin-left 20mm -margin-right 20mm document.md
# Verbose output
md2pdf -v document.md- Engineers writing design docs, runbooks, or technical specs in Markdown
- Teams using Mermaid diagrams (flowcharts, sequence diagrams) in their documents
- Consultants and security teams delivering reports as PDFs to clients
- Japanese-speaking developers tired of fighting font breakage in Markdown-to-PDF tools
- Anyone who manages docs in Git and needs to ship them as PDF artifacts
flowchart TD
A["Markdown (.md)"] --> E{format?}
E -->|pdf| B[goldmark parser]
B --> C[HTML builder]
B -->|extracts Mermaid blocks| D[mmdc CLI]
D -->|inline SVG| C
C --> F["Playwright / Chromium"]
F --> G[PDF output]
E -->|docx| J[Mermaid → PNG]
J --> H["pandoc (gfm reader)"]
H --> I[DOCX output]
PDF and DOCX take separate paths so each format reads from the source that renders best.
- PDF (default) — goldmark converts Markdown to HTML (GFM tables, fenced code blocks), Mermaid blocks are rendered to inline SVG via
mmdc, a self-contained HTML file is assembled with GitHub-flavored CSS and@font-facedeclarations for Noto Sans CJK JP, and a headless Chromium browser (via Playwright) prints it to PDF. - DOCX — the Markdown is sent directly to
pandoc(itsgfmreader, no HTML in between), so pandoc produces clean, Word-native paragraph and list styles. Mermaid blocks are rasterised to PNG and spliced back in as image references (Word cannot reliably display pandoc-embedded SVG). A generated reference document gives the output a readable, Japanese-friendly look: a 10.5pt body, compact blue headings, bordered GFM tables, and theYu Gothicfont (override with-docx-font).
Pandoc, md-to-pdf, and other Markdown-to-PDF tools are powerful and flexible. md2pdf focuses on a narrower use case: turning technical Markdown with Mermaid diagrams and Japanese (CJK) text into clean PDFs with minimal setup.
The screenshots below show what happens when you convert the same Japanese
PRD document (examples/06-japanese-document/input.md) with each tool out of
the box.
These are not bugs in Pandoc or md-to-pdf — both can produce great results once you configure CJK fonts and Mermaid plugins. md2pdf is just preconfigured for this exact combination, so it works without any extra setup.
If md2pdf fails with this error even though pip install playwright succeeded,
the Python interpreter md2pdf picked up does not match the one where
playwright is installed. This is common on macOS when multiple Pythons
coexist (system /usr/bin/python3, Homebrew, pyenv, venv).
Fix it by pointing md2pdf at the correct interpreter:
# One-off
md2pdf -python "$(which python3)" document.md
# Persistent
export MD2PDF_PYTHON="$(which python3)"
md2pdf document.mdUse -v to confirm which interpreter md2pdf is using.
# Unit tests only
go test ./internal/converter/ -run 'Test[^C]'
# All tests including integration (requires mmdc + python3 playwright)
go test ./...
# With verbose output
go test -v ./...Contributions are welcome! Please read CONTRIBUTING.md before opening a pull request.
MIT License — see LICENSE.

