Repository navigation
Markdown to PDF Comparison 2026 10 13
RayoMD 4.3.1 against glu, Qt 6's rich-text printing, Pandoc with Typst, WeasyPrint or XeLaTeX,
and md-to-pdf, converting the repository's tester.md, each tool as a fresh process, start to
exit. The tools render different Markdown subsets and look different, so this compares time to
a finished PDF, memory and install size, not identical output. The page renders below show what
each one makes of the same document.
- AMD Ryzen 5 PRO 4650GE (6 cores, 12 threads), Linux 7.0, an Arch Linux Docker container
(
archlinux:latestof 2026-10-12) with--network none, files on tmpfs. - Four pinned cores (
--cpuset-cpus=3,5,9,11) for the headline, one (--cpuset-cpus=3) beside it; nothing else heavy running. - Median of 20 runs after one uncounted warm-up, every output checked to be a complete PDF
(
qpdf --check, page count, a phrase found bypdftotext). -
tools/benchmark.py competitors(scripts/compare_markdown_pdf_tools.py), each command started in the document's folder. Its timing no longer waits with a timeout, which polled and added about 1.1 ms to every run on one core (commitf11b5c4); earlier reports were not affected on more than one core.
| Tool | Version | Command |
|---|---|---|
| RayoMD | 4.3.1 (release rayomd-4.3.1-linux-x64) |
rayomd --export IN OUT native modern normal --no-image-cache |
| glu | 0.0.46 (release glu-linux-amd64) |
glu -q -o OUT IN |
| Qt 6 | qt6-base 6.12.0 | a 110-line program: QTextDocument::setMarkdown, then print() to a QPrinter(HighResolution) with PDF output; IBM Plex Mono at 11 pt, QT_QPA_PLATFORM=offscreen
|
| Pandoc + Typst | Pandoc 3.11 (pandoc-cli), Typst 0.15.1 |
pandoc IN -o OUT --pdf-engine=typst … |
| Pandoc + WeasyPrint | Pandoc 3.11, WeasyPrint 70.0 | pandoc IN -o OUT -t html --pdf-engine=weasyprint … |
| md-to-pdf | 5.2.5, Node 26.11.1, Chromium 154 |
scripts/md_to_pdf_runner.cjs (A4, 20 mm margins) |
| Pandoc + XeLaTeX | Pandoc 3.11, TeX Live 2026 | pandoc IN -o OUT --pdf-engine=xelatex … |
The Pandoc routes read -f markdown+tex_math_single_backslash-raw_tex (so \[ … \] is display
math, as in RayoMD) with DejaVu Sans and DejaVu Sans Mono; md-to-pdf ran Chromium with
--no-sandbox (inside the container).
The same two documents as in Markdown-to-PDF Speed Comparison 2026-10-12: tester.md
without the lines that test fallbacks (two remote images, a missing local image and a formula
with an unknown TeX command, on which glu and XeLaTeX stop with an error and Pandoc waits on the
network).
| Document | Bytes | SHA-256 (first 16) | Contents |
|---|---|---|---|
tester-local.md |
4,880 | 4833c4ff1c15fe54 |
keeps the 1024×1024 RGBA mascot PNG |
tester-noimg.md |
4,750 | 0d35d7a801d21274 |
without images |
| Tool | Without images | × RayoMD | With the PNG | × RayoMD | Pages | Page size | Formulas |
|---|---|---|---|---|---|---|---|
| RayoMD | 1.48 ms | 1× | 7.75 ms | 1× | 5 / 6 | A4 | typeset |
| glu | 54.49 ms | 37× | 84.82 ms | 11× | 3 / 9 | A4 | TeX source |
| Qt 6 | 69.21 ms | 47× | 111.79 ms | 14× | 3 / 6 | A4 | TeX source |
| Pandoc + Typst | 345.62 ms | 234× | 375.99 ms | 49× | 4 / 6 | Letter | typeset |
| Pandoc + WeasyPrint | 967.80 ms | 654× | 1,238.19 ms | 160× | 4 / 6 | A4 | MathML text and TeX source |
| md-to-pdf | 1,804.97 ms | 1,220× | 1,902.96 ms | 246× | 3 / 6 | A4 | TeX source |
| Pandoc + XeLaTeX | 2,096.73 ms | 1,417× | 3,351.33 ms | 432× | 4 / 6 | Letter | typeset |
| Tool | Without images | × RayoMD | With the PNG | × RayoMD |
|---|---|---|---|---|
| RayoMD | 1.52 ms | 1× | 11.29 ms | 1× |
| glu | 63.96 ms | 42× | 98.00 ms | 8.7× |
| Qt 6 | 69.03 ms | 45× | 112.42 ms | 10× |
| Pandoc + Typst | 336.11 ms | 221× | 375.89 ms | 33× |
| Pandoc + WeasyPrint | 975.93 ms | 642× | 1,246.85 ms | 110× |
| Pandoc + XeLaTeX | 2,162.78 ms | 1,423× | 3,458.34 ms | 306× |
| md-to-pdf | 2,254.66 ms | 1,483× | 2,352.88 ms | 208× |
A second core helps RayoMD only with the PNG, which it re-encodes on up to four cores; it helps md-to-pdf (about 450 ms), XeLaTeX (about 100 ms) and glu (10 to 13 ms), and not Pandoc + Typst, Qt or WeasyPrint.
Peak RSS of tester-noimg.md (/usr/bin/time %M, median of 5). For the tools that run several
processes this is the largest one, not the sum.
| Tool | Peak RSS | Installed size beyond the Arch base image (approximate) |
|---|---|---|
| RayoMD (static edition in brackets) | 3.9 MiB (2.5 MiB) | 1.2 MiB (2.1 MiB) |
| glu | 33.2 MiB | 25 MiB |
| Qt 6 | 38.5 MiB | 373 MiB (comes with any Qt desktop) |
| md-to-pdf | 205.2 MiB | about 1.0 GiB (Node.js, npm, 39 MiB of modules, Chromium) |
| Pandoc + Typst | 239.3 MiB | about 0.65 GiB |
| Pandoc + WeasyPrint | 240.5 MiB | about 0.9 GiB |
| Pandoc + XeLaTeX | 339.9 MiB | about 1.4 GiB |
Install sizes are pacman -Qi "Installed Size" over each package's dependency closure, without
the 137 packages of the base image; the closures overlap.

- RayoMD, Typst and XeLaTeX typeset the formulas; glu, Qt and md-to-pdf print their TeX source; WeasyPrint prints MathML text followed by the TeX annotation.
- Qt prints
\pagebreakliterally and does not scale the 1024-pixel PNG to the page, so it is clipped; glu lays the PNG document out on 9 pages. - Every font is embedded except RayoMD's, which uses the PDF standard fonts where the text
allows it, and for formulas Times and Symbol. In this container, without
gsfonts, Poppler has no Symbol substitute and draws ∫ ∑ ≤ as nothing (visible in RayoMD's first page above); withgsfonts, as most desktops have, they render. The PDFs are valid either way. - Typography: Typst and XeLaTeX set justified, hyphenated text with fine spacing, which none of the fast tools do.
That comparison ran on Debian 12 without pinning, with Pandoc 3.12.1's static build and TeX Live
2022. Pandoc + Typst took 112 ms there and 346 ms here: Arch's pandoc-cli is linked against
Arch's Haskell library packages and takes 113 ms for pandoc --version alone, and typst compile took 203 ms on its own (median of 10). md-to-pdf went from 1,670 to 1,805 ms. RayoMD
4.0.0 took 1.6 ms there; 4.3.1 takes 1.5 ms.
The same day, the same container and harness, only RayoMD measured again with the 4.4.0 release binary (median of 20): without images 1.21 ms on four cores and 1.25 ms on one (4.3.1 measured 1.39 and 1.45 ms in that run), with the PNG 7.47 and 10.99 ms; peak memory 3.4 MiB (4.3.1: 3.9 MiB). Against the other tools' figures above, that is 45× faster than glu, 57× than Qt 6, 286× than Pandoc + Typst and 1,733× than Pandoc + XeLaTeX without images.
On 2026-10-14, the same machine, container and harness, only RayoMD measured again, the 4.6.0 and 4.4.0 release binaries in one run (median of 20): without images 1.37 ms on four cores and 1.39 ms on one (4.4.0: 1.27 and 1.30 ms in that run), with the PNG 7.64 and 11.24 ms (4.4.0: 7.58 and 11.06 ms); peak memory 3.6 MiB (4.4.0: 3.4 MiB); a further export in a running process 0.23 ms (4.4.0: 0.20 ms). 4.5 and 4.6 add work rather than remove it: formulas embed their fonts (the imageless PDF grows from 75 to 86 KB) and HTML is read. Against the other tools' figures above, that is 40× faster than glu, 51× than Qt 6, 252× than Pandoc + Typst and 1,530× than Pandoc + XeLaTeX without images.