Convert Markdown files to beautiful PDFs — locally, fast, no internet required.
**By Nana Amoako **
mdpdf turns your .md files into polished PDFs using headless Chrome — the same rendering engine that powers Notion, Linear, and the web. What you see in your Markdown preview is what you get in the PDF.
Four built-in themes, custom CSS support, watch mode, batch conversion, Mermaid/PlantUML diagram rendering, and a hard guard that rejects anything that isn't a Markdown file before conversion even starts.
- Four built-in themes — Apple, Notion, GitHub, Minimal (see Themes)
- Custom CSS — bring your own stylesheet and fully override the look (see Custom CSS)
- Mermaid & PlantUML diagrams — fenced code blocks render to inline SVG automatically (see Diagrams)
- Live progress bar — read → render → generate → save, with a percentage at every stage (see Progress)
- Zoom / print scale —
--zoom 85/--zoom 125, same idea as Notion's PDF export scale (see Zoom / print scale) - Watch mode —
-wauto-converts on every save - Batch conversion — convert multiple
.mdfiles in one command - HTML export —
--htmloutputs HTML instead of PDF, handy for previewing CSS changes - Configurable paper size & margins —
-p A4|Letter|Legal,-m <mm> - Code syntax highlighting — any highlight.js theme via
--highlight(see Highlight styles) - Flexible output location — same-directory default, or redirect with
-o(see Output location) - File guard — only
.md/.markdownare accepted, rejected before any conversion work starts (see File guard) - Auto-open — opens the finished PDF in Preview on macOS (disable with
--no-open)
Requires Node.js ≥ 18
# Clone and install
git clone https://github.com/nanadotam/mdpdf-cli.git
cd mdpdf-cli
npm install
npm link # makes `mdpdf` available globally in your terminal
mdpdf <file.md> [more files...] [options]
| Flag | Description | Default |
|---|---|---|
-o, --output <path> |
Output file or directory | Same dir as source |
-t, --theme <name> |
Built-in theme (see below) | apple |
-s, --style <file> |
Custom CSS file (overrides --theme) |
— |
-p, --paper <size> |
Paper size: A4 · Letter · Legal |
A4 |
-m, --margins <mm> |
Margins in mm — one value or top,right,bottom,left |
20 |
-z, --zoom <percent> |
Print scale, e.g. 85, 90, 125 — same idea as Notion's PDF export scale |
100 |
-w, --watch |
Watch file for changes and auto-convert | off |
--no-open |
Don't open the PDF in Preview after conversion | auto-opens |
--html |
Output an HTML file instead of a PDF | off |
--highlight <style> |
Code syntax theme (github, atom-one-dark, monokai…) |
github |
-V, --version |
Show version | |
-h, --help |
Show help |
| Name | Feel |
|---|---|
apple |
San Francisco (SF Pro) · Apple design language · Dark code blocks |
notion |
Inter · Clean Notion-like spacing · Warm neutrals |
github |
GitHub Markdown · Developer-friendly · Familiar |
minimal |
Georgia serif body · Wide margins · Client-ready |
mdpdf report.md -t notion
mdpdf report.md -t github
mdpdf report.md -t minimal
# Convert with default Apple theme — opens PDF automatically
mdpdf report.md
# Notion look, Letter paper
mdpdf report.md -t notion -p Letter
# Save to a specific directory
mdpdf report.md -o ./exports/
# Custom CSS — bring your own style
mdpdf report.md -s ./my-brand.css
# Watch mode — auto-converts on every save
mdpdf report.md -w
# Batch conversion — multiple files at once
mdpdf file1.md file2.md file3.md -o ./out/
# Dark code blocks with atom-one-dark highlight
mdpdf report.md --highlight atom-one-dark
# Tight margins for a dense layout
mdpdf report.md -m 12
# Top/bottom 20mm, left/right 30mm
mdpdf report.md -m 20,30
# Output HTML instead (useful for debugging your CSS)
mdpdf report.md --html
# Convert without auto-opening Preview
mdpdf report.md --no-open
mdpdf only accepts .md and .markdown files. Anything else is rejected immediately — before any conversion starts.
$ mdpdf notes.txt
✗ Not a Markdown file: notes.txt [.txt]
→ mdpdf only accepts .md or .markdown files.
$ mdpdf invoice.pdf
✗ Not a Markdown file: invoice.pdf [.pdf]
→ mdpdf only accepts .md or .markdown files.
Pass any CSS file with -s to fully control the output:
mdpdf report.md -s ./brand.css
Use --html first to preview your styles in a browser before committing to PDF:
mdpdf report.md -s ./brand.css --html --no-open
open report.html
Fenced code blocks written in Mermaid or PlantUML are rendered to inline SVG before the PDF is generated:
```mermaid
flowchart TD
A[Request] --> B{Valid?}
B -->|Yes| C[Process]
B -->|No| D[Reject]
```
```plantuml
@startuml
Alice -> Bob: hello
@enduml
```
- Mermaid renders locally via headless Chrome — no internet required.
- PlantUML is rendered remotely through Kroki — requires internet access.
pumlis accepted as an alias forplantuml.
If a diagram fails to render (bad syntax, no network for PlantUML), mdpdf prints a warning and leaves the rest of the document intact.
Every conversion shows a live progress bar through the read → diagram-render → generate → save pipeline:
█████████████████░░░░░░░░░ 62% Generating PDF
In non-interactive shells (CI, piped output) it falls back to plain [N%] message lines instead of redrawing in place.
--zoom maps directly to the PDF's print scale — the same control Notion's "Export to PDF" dialog exposes. Values below 100 shrink content (more page per sheet, smaller text); values above 100 enlarge it. Accepts 10–200:
mdpdf report.md --zoom 85 # or -z 85 — a common preference for dense docs
mdpdf report.md --zoom 125 # zoom in for readability
By default, the PDF lands in the same directory as your Markdown file with the same name:
docs/VENUE_OWNER_ANALYSIS.md → docs/VENUE_OWNER_ANALYSIS.pdf
Use -o to redirect:
mdpdf docs/report.md -o ./exports/ # → exports/report.pdf
mdpdf docs/report.md -o ./exports/final.pdf # → exports/final.pdf
Pass any highlight.js theme name to --highlight:
github (default) atom-one-dark monokai dracula
vs2015 night-owl nord gruvbox-dark
MIT © Nana Amoako