PDFPipe

Comparison

A PhantomJS alternative that is actually maintained

PhantomJS was the go-to headless browser for PDF generation in Node.js and Python projects throughout the early 2010s. Its maintainer stepped down in 2018 and the project has received no security patches since. If your codebase still pulls in phantom, node-phantom, phantom-html-to-pdf, or html-pdf from npm, all of those are wrappers around the same abandoned binary. PDFPipe replaces the entire stack with a single HTTP call.

How they compare

PDFPipePhantomJS
Maintenance statusActively maintainedAbandoned since 2018, no security patches
Browser engineFull modern browser engineWebKit 534 (circa 2012)
CSS supportGrid, flexbox, CSS variables, web fontsPartial CSS 2.1, limited CSS 3
DeploymentREST API, zero servers to runBinary process you install and host
URL-to-PDFPOST a URL, get a PDF backRequires scripting a page.open() call
SSRF protectionSandboxed, blocks private and metadata IPsNone
Document storageOptional hosted storage with signed URLsNone
Pricing500 free documents a month, flat per-document afterFree but you pay for infrastructure

Before and after

A typical PhantomJS PDF script spins up a child process, writes a script file, waits for it to exit, and reads the output. The PDFPipe version is one fetch call.

Before (phantom-html-to-pdf)

import pdf from "phantom-html-to-pdf";

pdf()("<html><body><h1>Invoice</h1></body></html>", (err, result) => {
  if (err) throw err;
  result.stream.pipe(fs.createWriteStream("invoice.pdf"));
  result.process.kill();
});

After (PDFPipe)

const res = await fetch("https://api.pdfpipe.xyz/v1/pdf", {
  method: "POST",
  headers: { Authorization: "Bearer pp_live_your_key" },
  body: JSON.stringify({
    html: "<html><body><h1>Invoice</h1></body></html>",
    options: { format: "A4" },
  }),
});
fs.writeFileSync("invoice.pdf", Buffer.from(await res.arrayBuffer()));

Why the npm wrappers are all deprecated

Every PhantomJS npm package (html-pdf, phantom-html-to-pdf, node-phantom, phantom) shells out to the same PhantomJS binary. That binary has not received a security patch since April 2018, does not support modern Node.js ARM builds, and frequently triggers antivirus flags in CI environments. The wrapper maintainers themselves recommend migrating away. PDFPipe removes the binary entirely: your app makes an HTTP request and receives a PDF.

When to stay with a local renderer

If your documents contain highly confidential data that must never leave your network, a self-hosted renderer makes sense. In that case, look at Puppeteer or Playwright with Chromium rather than PhantomJS. For everything else, PDFPipe handles rendering, scaling, and infrastructure so you do not have to.

Try PDFPipe on the live playground with no signup, then read the docs.

See pricing →