Public API is now available! Convert Markdown to images programmatically with 50 free requests/month.
Back to Blog
Thursday, January 1, 1970

How to Batch Convert Multiple Markdown Files to PDF

How to Batch Convert Multiple Markdown Files to PDF

The 30-second answer

Three common batch jobs:

  1. One Markdown file → one PDF, repeated for many files: md-to-pdf *.md (npm CLI).
  2. Many Markdown files → one combined PDF (a book, a report with chapters): pandoc chapter*.md -o book.pdf.
  3. Many Markdown files → one PDF on each commit: GitHub Actions workflow with the npm CLI.

The browser-based /markdown-to-pdf is single-file; for batch jobs you want a CLI. This guide walks through the three scenarios with copy-paste commands and a few gotchas.

Scenario 1 — N → N (one PDF per Markdown file)

The simplest case. You have chapter01.md, chapter02.md, ..., and you want chapter01.pdf, chapter02.pdf, ...

npm install -g md-to-pdf
md-to-pdf 'chapters/*.md'

That's it — by default it writes a .pdf next to each .md. Add a stylesheet to control look:

md-to-pdf 'chapters/*.md' --stylesheet ./style.css

If you have hundreds of files and want to parallelize:

ls chapters/*.md | xargs -P 4 -I {} md-to-pdf {}

-P 4 runs four PDFs in parallel. Past 4-8 you'll be limited by the headless Chromium spin-up cost.

Scenario 2 — N → 1 (combine many .md into one PDF)

This is what you want for books, technical reports, or onboarding docs split across files.

Pandoc (best for ordered chapters)

pandoc chapter01.md chapter02.md chapter03.md -o book.pdf

Gotcha: filename order matters. Pandoc concatenates in argument order, not alphabetical, so use shell expansion intentionally:

pandoc chapter*.md -o book.pdf  # alphabetical order, fine if you've zero-padded

For a table of contents:

pandoc chapter*.md --toc -o book.pdf

With proper LaTeX page breaks between chapters:

pandoc chapter*.md --toc --top-level-division=chapter -o book.pdf

Cat-and-convert (works with any Markdown→PDF tool)

If you don't want to install Pandoc, concatenate first:

echo "" > combined.md
for f in chapter*.md; do
  cat "$f" >> combined.md
  echo -e "\n\n<div style=\"page-break-before: always;\"></div>\n\n" >> combined.md
done
md-to-pdf combined.md

The <div> injects a page break between chapters. Crude but reliable.

Scenario 3 — CI/CD (PDF on every commit)

A GitHub Actions workflow that produces PDFs on every push to main:

# .github/workflows/build-pdfs.yml
name: Build PDFs
on:
  push:
    branches: [main]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm install -g md-to-pdf
      - run: md-to-pdf 'docs/**/*.md'
      - uses: actions/upload-artifact@v4
        with:
          name: pdfs
          path: 'docs/**/*.pdf'

This runs md-to-pdf on every Markdown file under docs/, uploads the PDFs as a build artifact. Trigger on tag push and you can attach them to a Release.

Common gotchas

  1. Image paths break in the combined PDF. If chapter01.md references ./images/a.png from inside its own directory, concatenating into a single file breaks that path. Either rewrite paths to be absolute, embed images as data URIs, or use Pandoc's --resource-path=. to add lookup directories.
  2. Front-matter conflicts. Each .md file may have its own YAML front-matter. Pandoc takes the first; md-to-pdf per-file mode reads each file's own. Strip front-matter before concatenating if it conflicts.
  3. Page numbers reset between chapters. Pandoc handles this with --top-level-division=chapter; the cat-and-convert path doesn't, so page numbers are continuous (which is usually what you want for a book).
  4. Unicode / CJK fonts. For Chinese, Japanese, Korean: Pandoc with XeLaTeX needs --pdf-engine=xelatex -V mainfont:"Source Han Serif CN". The headless-Chromium tools (md-to-pdf, /markdown-to-pdf) inherit the system font stack and just work.
  5. Memory for large batches. 500+ files via md-to-pdf will spin up Chromium hundreds of times. Use xargs -P to parallelize but cap parallelism at CPU core count.

When to use the web tool vs the CLI

  • One file occasionally/markdown-to-pdf. Faster to open the page than to install npm.
  • Same template, dozens of files, one-offmd-to-pdf CLI.
  • Same template, many files, on every commit → CLI in CI.
  • Books, reports, multi-chapter → Pandoc with --top-level-division=chapter --toc.
  • Heterogeneous templates per chapter → generate per-file PDFs (Scenario 1) and merge them with pdfunite or qpdf afterward.

For more on each tool's tradeoffs see our Markdown to PDF method comparison and the deep dive on code highlighting in PDF.

Merging existing PDFs (when batch-conversion happened separately)

If you already produced separate PDFs and want to concatenate without re-rendering:

# pdfunite (poppler-utils)
pdfunite chapter01.pdf chapter02.pdf chapter03.pdf book.pdf

# or qpdf
qpdf --empty --pages chapter*.pdf -- book.pdf

# or ghostscript
gs -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -sOutputFile=book.pdf chapter*.pdf

No re-render means lossless and fast (under a second for 100 files).

FAQ

Can I batch-convert with the web /markdown-to-pdf?

The web tool is single-file. For batch jobs use the CLI; for one-off use the web tool. Some users zip up a batch result manually after running CLI conversions.

How do I preserve code highlighting across all files in batch mode?

The CLI inherits whatever stylesheet you pass with --stylesheet. Use the same theme on every file for consistency. Read more in Markdown to PDF with code highlighting.

What's the upper limit on a single combined PDF?

Functionally unlimited — we've seen 5000-page combined PDFs work fine. Practically: search performance in PDF readers degrades past ~1000 pages, and email attachments cap around 25 MB. For massive docs split into volumes.

Is there an API for batch conversion?

Yes — our Markdown to Image API supports a format=pdf parameter, so you can script batch conversion from any language with HTTP. Useful when you don't want a Node dependency in CI.

Does Pandoc preserve Mermaid diagrams in batch mode?

Not natively. You need pandoc-mermaid-filter or convert Mermaid to SVG first, then reference the SVG. The npm CLI also needs a markdown-it Mermaid plugin for batch.

Wrapping up

The right batch tool depends on what you're producing:

  • 1-to-1 PDFs → md-to-pdf '*.md'
  • Many-to-1 book → pandoc chapter*.md --toc -o book.pdf
  • Continuous build → GitHub Actions + npm CLI
  • Concatenate existing PDFs → pdfunite or qpdf

If this is a one-off batch and you don't have any of these installed, the lowest-friction path is: run the web /markdown-to-pdf once per file in a tab, then pdfunite the results.

Batch Convert Multiple Markdown Files to PDF (CLI, Pandoc, CI) | MarkdownToImage