The npm wkhtmltopdf wrapper still pulls roughly 50,000 downloads a week, and by the project's own status page the stack underneath it is done. The wrapper last published in May 2021, the maintainer archived the binary in January 2023, and GitHub archived the entire organisation in July 2024. The rendering engine it spawns is WebKit, frozen at 2012, and none of that has changed as of 2026.
None of that is a third-party characterisation, it is the project describing itself. IronPDF for Node.js does the same HTML-to-PDF job through a current, actively patched Chromium engine, which is the difference this piece is about.
Full disclosure. We build IronPDF for Node.js at Iron Software, and this read looks at where wkhtmltopdf's archived engine and unpatched CVEs cost a team and where IronPDF covers the same job on a maintained engine.
How do the two compare on engine and security?
Every row here traces back to the project's own status page, GitHub history, or the CVE records.
| Capability | wkhtmltopdf (npm wrapper) | IronPDF for Node.js |
|---|---|---|
| Rendering engine | WebKit, frozen since 2012 | Current Chromium |
| Modern CSS (flexbox, grid) | Renders incorrectly | Full support |
| npm wrapper last published | May 2021 | Active |
| Upstream binary | Archived January 2023 | Actively maintained |
| Known CVEs in own code | Two, both unpatched | None found |
| Native binary in the image | Required, wkhtmltopdf() spawns it |
None, PdfDocument.fromHtml
|
Table 1. How wkhtmltopdf and IronPDF for Node.js compare on engine, maintenance, and security, from the project's own metadata and the GitHub Advisory Database.
What does a 2012 engine leave exposed?
The engine wkhtmltopdf spawns is Qt 4 on WebKit, frozen since 2012 by the project's own account, so wkhtmltopdf does not render modern CSS the way a current browser does, and flexbox, grid, and everything from the last decade of layout come out wrong. That is not a bug anyone will fix, because there is no one left to fix it.
The wkhtmltopdf binary also cannot be patched for either of its two confirmed CVEs. CVE-2020-21365 is a directory traversal that lets crafted HTML read local files under the default configuration, and CVE-2022-35583 is a critical server-side request forgery through an injected iframe pointing at internal addresses. If any of the HTML your app renders comes from user input, a form field, an uploaded template, an embedded comment, these are reachable today and no fix is coming. And because it spawns a native binary, wkhtmltopdf cannot run without that binary baked into every container image or serverless layer, which an in-process library does not need.
One clarification is worth making, because the mix-up is common. You will sometimes see CVE-2024-13285 cited against wkhtmltopdf, but it belongs to a Drupal module of the same name, not the binary this wrapper spawns. Setting that miscited one aside, the two that do belong to the binary, the directory traversal and the SSRF, are the ones that stay unpatched with no maintainer to fix them.
A Chromium engine that still ships fixes
IronPDF renders the same HTML through a Chromium engine that is patched on a current release cadence, with no separate binary to install into the image.
import { PdfDocument } from "@ironsoftware/ironpdf";
const invoice = await PdfDocument.fromHtml(
"<h1>Invoice #1042</h1><p>Total due: $250.00</p>"
);
await invoice.saveAs("invoice.pdf");
That renders a document on an engine that still ships fixes, so modern CSS lands the way a browser shows it and a newly found issue has a maintainer behind it. You can pull IronPDF for Node.js from npm and run this in a couple of minutes, and the guide on HTML to PDF without a frozen engine walks the path end to end.
IronPDF renders on a maintained engine
The one case for wkhtmltopdf is a static document with no user input anywhere near it, running on a container already built around the frozen binary. That covers few real apps, though, since any HTML that includes user input makes both CVEs reachable, and modern CSS already renders wrong on a 2012 engine whether the input is trusted or not.
If your Node app is calling this wrapper today, the choice is between staying on an archived stack and moving to IronPDF for Node.js on a maintained engine. IronPDF for Node.js has a free trial if you want to run your own HTML through it before deciding.
Is the npm wkhtmltopdf wrapper still running somewhere in your stack, and what is holding up the move? Tell us in the comments, we would like to know whether it is inertia or something more specific.
wkhtmltopdf is distributed under the LGPL licence, and is not affiliated with Iron Software. The details above are drawn from the project's own status page, GitHub history, and the GitHub Advisory Database. If something has changed since, correct us in the comments.













