Blog/Compare

wkhtmltopdf alternatives in 2026

Compare··7 min read

Stop installing the wkhtmltopdf binary for new work. The GitHub repo is archived, the last stable release is 0.12.6 (June 2020), and the engine is a Qt 4 WebKit fork the project’s own status page dates to 2012. For HTML you already own, print with Chromium: a hosted HTML to PDF API (RelayPDF is one) or a self-hosted Chromium wrapper such as Gotenberg. Use Prince or DocRaptor when the document needs CSS Paged Media that Chromium still does poorly. Keep wkhtmltopdf only as a compatibility engine for templates you cannot retune yet. RelayPDF defaults to Chromium on POST /v1/pdf and still exposes wkhtmltopdf on POST /v1/convert. Product: https://relaypdf.com/html-to-pdf. Engine compare: https://relaypdf.com/compare/wkhtmltopdf. Convert docs: https://relaypdf.com/docs/convert.

Why the binary is finished

wkhtmltopdf is a command-line wrapper around Qt WebKit. That was a reasonable 2010s answer when Chrome print-to-PDF was weak and Prince was expensive. The maintainer’s status page (https://wkhtmltopdf.org/status.html, dated around the 0.12.6 release) is explicit: Qt 4 has been unsupported since 2015; the WebKit inside it has not been updated since 2012; Qt deprecated QtWebKit in 2015 and removed it in Qt 5.6 (2016). A 0.13 rebase onto a newer QtWebKit never shipped as a supported engine. The GitHub project is archived. There is no current upstream for security or CSS.

You can still download a static binary. Nobody ships engine-level patches on a browser cadence. Treat it as frozen software.

CSS the engine cannot print

A 2012-era WebKit predates CSS Grid (widely shipped around 2017) and does not implement the Flexbox, custom properties, and webfont behavior current invoice and dashboard templates assume. Layouts that look correct in Chrome print as stacked blocks, missing columns, or ignored @page rules. JavaScript is the old in-process WebKit1 runtime, not Blink. If the template was built in a modern browser, wkhtmltopdf is the wrong renderer.

RelayPDF’s compare page states the same split: Chromium is the default for modern CSS; wkhtml compatibility is an opt-in on /v1/convert, not the print path for new HTML.

Security class, not a CVE list

This article will not inventory CVE IDs. The engine is unmaintained WebKit. The project’s recommendations say not to run wkhtmltopdf on untrusted HTML or JavaScript: a hostile document can take over the host process. Expected class: SSRF-style fetches, script in the renderer, memory-safety bugs that will not get a vendor patch.

If any fragment of the document comes from a customer, a webhook, or a CMS field, do not point a local wkhtmltopdf at it. Move the job to a renderer that is patched on a browser schedule, or isolate the old engine so it cannot reach your network or secrets. RelayPDF’s URL source on /v1/pdf rejects private, loopback, and metadata hosts. That is a boundary, not a claim that every convert engine is safe for attacker-controlled HTML.

The three replacements

Pick by layout model and who runs the process. Chromium matches what designers already preview. Gotenberg is that engine in a container you operate. Prince (and DocRaptor, which hosts Prince) is a paged-media typesetter, not a browser.

TopicChromium API (RelayPDF)Self-host GotenbergPrince / DocRaptor
EngineManaged Chromium on POST /v1/pdfHeadless Chromium in your Docker/K8s (LibreOffice in the same image)PrinceXML (DocRaptor is the hosted Prince API)
CSS / JSCurrent Blink: Flex, Grid, webfonts, printBackground default trueSame Chromium class; you pin the image tagStrong CSS Paged Media, footnotes, named pages; not a Chrome preview
What you callJSON POST; html as UTF-8, not Base64. Node client.pdf.fromHtml()multipart/form-data to /forms/chromium/convert/html|url (index.html convention)Prince CLI or DocRaptor HTTP API
You operateBearer key + prepaid wallet. No Chrome on your boxImage, RAM, concurrency, Chromium updates, auth in front of the portA license (Prince) or a SaaS invoice (DocRaptor)
wkhtml left behindOptional: POST /v1/convert with engine wkhtmltopdf ($0.025). Chromium stays defaultYou can keep a second container if you must; Gotenberg’s HTML path is ChromiumDifferent layout model. Do not expect pixel match with old wkhtml output
Sibling workOffice on /v1/convert (LibreOffice $0.04); merge /v1/pdf/merge; tools, barcodes, zipLibreOffice + PDF utilities in-process if you run themDocRaptor also does HTML to XLS/XLSX. Not a general PDF toolkit
When it is the right toolYou have HTML/Markdown/a template and want a document endpointData must not leave the network and you already run containersBooks, footnotes, mixed page sizes, paged-media CSS Chromium will not honor

Chromium API: POST /v1/pdf

Documented at https://relaypdf.com/docs/pdf. Send exactly one source field (html, url, markdown, or templateId) as UTF-8 JSON. HTML is not Base64. Optional filename must end in .pdf. Default response is binary application/pdf. response: "url" returns JSON with a public download that expires in 24 hours. response: "async" plus an optional HTTPS callbackUrl defers the job. printBackground defaults to true. timeout on options is a Chromium budget, max 60,000 ms. waitUntil values on the product page: load, domcontentloaded, networkidle0, networkidle2.

RelayPDF: Chromium print

curl https://api.relaypdf.com/v1/pdf
  -H "Authorization: Bearer pdf_live_..."
  -H "Content-Type: application/json"
  -d '{"html":"<h1>Invoice 1042</h1>","filename":"invoice.pdf"}'
  --output invoice.pdf

That is the path for new templates. Office files still go to POST /v1/convert. Merges go to POST /v1/pdf/merge. Do not send .docx through /v1/pdf. Print controls (format, margins, headerTemplate / footerTemplate, waitUntil) are on https://relaypdf.com/docs/options. Failed renders return structured JSON and are not billed.

Self-host Gotenberg

Gotenberg is a Docker API: Chromium for HTML, URL, and Markdown; LibreOffice for Office. You POST multipart/form-data, not a JSON html string. The common HTML route expects a file named index.html. Official getting-started is docker run on port 3000 and POST /forms/chromium/convert/url or /forms/chromium/convert/html (https://gotenberg.dev/). That is a real alternative if the constraint is residency or an existing cluster, not if the constraint is “I do not want to run Chrome.”

You then own image upgrades, worker RAM, render timeouts, and whatever you put in front of an open convert port. A managed API is the same engine class without that fleet. RelayPDF’s live compare for that split is https://relaypdf.com/compare/gotenberg; this article will not rewrite that page.

Prince and DocRaptor

Prince is a commercial HTML/XML to PDF typesetter with first-class CSS Paged Media (named pages, footnotes, running headers, floats to page edges). The wkhtmltopdf status page already pointed report authors at Prince or WeasyPrint for HTML they control. DocRaptor is a hosted Prince API — useful if you want that engine without installing a license locally. It is the wrong default when the template is a responsive web page that must match Chrome.

When RelayPDF still runs wkhtmltopdf

Some shops have a folder of HTML tuned to wkhtml quirks (its TOC flag, its margin flags, its old box model). Rewriting those in one sprint is optional. RelayPDF keeps the binary as a convert engine so you can move the HTTP, auth, and wallet first, then retune templates onto Chromium. Pricing lists that line separately: wkhtmltopdf on /v1/convert is $0.025 per successful job; LibreOffice convert is $0.04; Chromium HTML/URL/Markdown on /v1/pdf is $0.015.

Convert docs: exactly one of html, url, or file (file needs sourceFilename). to defaults to pdf. engine is libreoffice (default) or wkhtmltopdf. wkhtmltopdf only accepts html or url to pdf, and can set options.toc. 503 convert_unavailable means the document worker is cold or unreachable and is not billed.

RelayPDF: engine wkhtmltopdf on /v1/convert

curl https://api.relaypdf.com/v1/convert
  -H "Authorization: Bearer pdf_live_..."
  -H "Content-Type: application/json"
  -d '{
    "html": "<h1>Legacy report</h1>",
    "to": "pdf",
    "engine": "wkhtmltopdf",
    "filename": "legacy.pdf"
  }'
  --output legacy.pdf

Use that call as a bridge, not as the destination. New HTML should hit /v1/pdf. Compare page wording: Chromium remains default; wkhtml is compatibility mode.

Migration

Do not swap flags one-for-one and expect pixel identity. You are changing engines. Freeze a golden PDF from the old binary, then print the same HTML through Chromium and diff pages that use Flex, Grid, webfonts, or JS charts.

  1. Inventory templates. Anything built in the last several years almost certainly needs Chromium, not wkhtml.
  2. If a template only works on wkhtml, call POST /v1/convert with engine wkhtmltopdf (or keep a locked binary) until you rewrite CSS.
  3. Map print options on /v1/pdf: format, margins, printBackground, headers/footers, waitUntil, timeout. Defaults are Chromium’s, not wkhtml’s.
  4. Inline HTML or use a public URL. file:// and localhost are not a public url source.
  5. Office files stay on /v1/convert with LibreOffice. Merges stay on /v1/pdf/merge.

Limits

  • Chromium on /v1/pdf maxes the render budget at 60 seconds. Cut work on script-heavy pages that never go idle.
  • URL fetch is public-web only. Intranet prints stay in-process or become inline HTML.
  • You get documented print options, not every wkhtml CLI flag and not every CDP method.
  • wkhtmltopdf on /v1/convert does not grow Flex/Grid support. It only avoids a local binary.
  • This article does not claim OCR, e-sign, PDF/A, or HIPAA. Those are not on the source pages.

Pricing (verified)

Live rate card at https://relaypdf.com/pricing: prepaid wallet, no monthly tiers. Failed, invalid, unauthorized, and rate-limited requests are never billed. Credit never expires.

  • HTML / URL / Markdown to PDF or screenshot (/v1/pdf, /v1/images): $0.015 per successful operation.
  • Handlebars template to PDF (/v1/pdf + templateId): $0.015.
  • LibreOffice convert $0.04, wkhtmltopdf $0.025, PDF tools / barcodes / zip $0.005, AI template generation $0.05.
  • $5 credit at signup, no card required. Top-up bonuses from 5% ($20 to $21) to 15% ($500 to $575).

A thousand Chromium invoices at $0.015 is $15 plus any top-up bonus. The same thousand on engine wkhtmltopdf is $25. Price the compat engine as a temporary tax, not as the steady-state printer. Request body: https://relaypdf.com/docs/pdf. Convert: https://relaypdf.com/docs/convert. Hub: https://relaypdf.com/docs.

Ready to generate?

One API for HTML, Markdown, URLs, and Office. REST, SDK, CLI, or MCP.