HTML to PDF in Node.js

Render HTML to PDF from Node.js with the built-in fetch — no Puppeteer, no Chromium download. One POST request, copy-paste example inside.

Last updated

Skip Puppeteer and the Chromium download entirely — Node's built-in fetch (Node 18+) is enough:

import { writeFile } from "node:fs/promises";

const res = await fetch("https://api.pdfrender.dev/v1/render", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": process.env.PDFRENDER_KEY, // optional — anonymous works too
  },
  body: JSON.stringify({
    html: "<h1>Hello</h1><p>Rendered from Node.js.</p>",
    filename: "hello.pdf",
  }),
});
if (!res.ok) throw new Error(`render failed: ${res.status} ${await res.text()}`);
await writeFile("hello.pdf", Buffer.from(await res.arrayBuffer()));

The response body is the PDF itself (application/pdf), so there is nothing to decode — write the bytes and you are done.

What renders

The engine is WeasyPrint: HTML + CSS, including print-specific CSS (@page, margin boxes, page counters). JavaScript in your document does NOT execute — if your page needs client-side JS to reach its final state, render that state into the HTML server-side first. External http(s) images, fonts and stylesheets are not fetched; inline them as data: URIs (how).

Try it free

Try it free — 100 renders a month, no card — or try the browser-based tool with zero setup.

FAQ

Can I generate a PDF in Node.js without Puppeteer?
Yes. One POST with the built-in fetch replaces Puppeteer entirely: no Chromium download, no headless browser to keep alive, and no memory sizing for concurrent renders.
How do I write the PDF response to disk in Node?
Take the arrayBuffer() from the response, wrap it in Buffer.from(), and pass it to fs.writeFile. The response body is the PDF itself, not JSON.
Does this work in serverless functions?
Yes, and it is the main reason to prefer it. A bundled Chromium usually exceeds serverless size and memory limits; an HTTP call does not.