The one-line difference
wkhtmltopdf is a command-line tool that renders HTML via an old fork of Qt WebKit. It's unmaintained — the project archived itself in early 2023, the underlying Qt WebKit hasn't shipped a security release in years, and most Linux distributions have removed the package. makesPDF is a hosted REST API with an actively maintained, deterministic layout engine, PDF/A-2A + PDF/UA-1 compliant by construction.
Feature matrix
| wkhtmltopdf | makesPDF | |
|---|---|---|
| Maintenance status | Archived 2023, no security fixes | Actively developed |
| Shape | CLI binary + ancient Qt WebKit | Hosted REST API (/api/v1/*) |
| Authoring surface | HTML + CSS (pre-2016 WebKit features) | Markdown, builder DSL, JSON |
| Runtime | Your server + Qt deps | Cloudflare Workers (we host) |
| Modern CSS | No (no flexbox/grid/modern fonts) | N/A — different model |
| Tagged PDF (PDF/UA-1) | No | Yes, by default |
| PDF/A archival | No | Yes (PDF/A-2A) |
| veraPDF-validated | No | Yes |
| Security posture | Stale Qt WebKit, known CVEs | Worker sandbox, no shared browser |
| Agent-first | No | Yes — public skill file, MCP server, x402-payable |
| License | LGPL-3.0 (binary distribution issues) | Proprietary hosted; skill file MIT |
Same input, two outputs
A simple report.
wkhtmltopdf — HTML in, CLI invocation:
cat > report.html <<'EOF'
<!doctype html>
<html><body style="font-family: sans-serif; padding: 40px;">
<h1>Hello, Ada</h1>
<p>Welcome to the report.</p>
</body></html>
EOF
wkhtmltopdf --page-size A4 report.html hello.pdf
…assuming you can still get the binary installed. Recent Ubuntu/Debian no longer ship it; you're either pinning a third-party deb or building from source against an obsolete Qt.
makesPDF — one HTTP call:
curl -X POST https://makespdf.com/api/v1/md \
-H "Authorization: Bearer $MAKESPDF_API_KEY" \
-H "Content-Type: application/json" \
-d '{"markdown": "# Hello, Ada\n\nWelcome to the report."}' \
-o hello.pdf
Why people switch
- It's archived. No bug fixes, no CSS updates, no security patches. Every audit cycle this becomes harder to defend in a procurement review.
- The Qt WebKit underneath is from 2016. Modern CSS (flexbox, grid, gap, custom properties) doesn't render correctly. Web fonts via
@font-facework inconsistently. SVG support is partial. - Compliance. wkhtmltopdf doesn't emit a structure tree, so PDF/UA-1 is impossible without external remediation. The same deadline pressure (ADA Title II tier 1, EAA) that's pushing teams off Chromium is also pushing them off wkhtmltopdf.
- Operational footprint. Distros are removing the package. Self-built binaries are pinned to specific glibc/Qt combos. Hosted means none of that lives in your image.
- Agents. A CLI subprocess is fine for cron jobs; it's the wrong primitive for an LLM. A REST endpoint with a skill file is.
When wkhtmltopdf is still defensible
- A strictly internal, air-gapped report that already works and isn't being audited. "If it ain't broke" is a real argument for legacy tools.
- A migration project where wkhtmltopdf is the temporary state and you've already scheduled the cutover.
In every other case, the project being archived is the headline. New code shouldn't start there.
Migration
Most wkhtmltopdf invocations are templating an HTML string from a CMS or report generator. Two common paths:
- Markdown — generate markdown instead of HTML and POST to
/api/v1/md. Headings, tables, alerts, footnotes, Mermaid diagrams all render natively. - DSL — for invoices/receipts/statements with precise table layouts, the builder DSL replaces the CSS-print stylesheet with a tiny typed surface.
Both endpoints are language-agnostic — your wkhtmltopdf shell-out becomes an HTTP call.