Skip to content
Guide

Getting started

Install, render, save. On Node and Bun you get the high-fidelity Chromium engine without a second step; in the browser there's nothing extra to install at all.

Install

bash
npm i htmlpdfx

On Node and Bun this also brings Puppeteer — which bundles Chromium — as an optional dependency, so Chromium works out of the box.

Because it's optional, the install stays resilient: if the Chromium download is unavailable (CI caches, offline, browser-only targets), npm i htmlpdfx still succeeds and the built-in renderer is used instead.

Prefer a different driver? Install one and htmlpdfx detects it automatically:

bash
npm i playwright        # or: playwright-core / puppeteer-core

Render your first PDF

ts
import { toPdf } from "htmlpdfx";

const pdf = await toPdf("<h1>Hello</h1>", { format: "a4", margin: 15 });
await pdf.save("hello.pdf");
ts
import { toPdf } from "htmlpdfx";

const pdf = await toPdf(
  { element: document.getElementById("invoice")! },
  { format: "a4", margin: 12 },
);
await pdf.download("invoice.pdf");
ts
import htmlpdfx from "htmlpdfx";

await htmlpdfx()
  .from(document.getElementById("invoice")!)
  .set({ margin: 10, pageBreak: { avoid: [".row"] } })
  .save("invoice.pdf");

Take the bytes wherever you need them

Every render returns a PdfResult, so the same call works for a file, an HTTP response, or a download:

ts
const pdf = await toPdf(html);

pdf.bytes; // Uint8Array
pdf.pageCount; // number of pages
pdf.engine; // "chromium" | "canvas" — which tier actually ran

await pdf.save("out.pdf"); // Node / Bun: write to disk
await pdf.download("out.pdf"); // Browser: trigger a download
pdf.toBlob(); // Blob
pdf.toDataUrl(); // data: URL
pdf.toArrayBuffer(); // ArrayBuffer

Inputs

Pass a string, a URL, a file, or a live DOM node. The input decides which engines can serve it:

ts
toPdf("<h1>hi</h1>"); // HTML string          — either engine
toPdf({ html, baseUrl: "https://cdn.example.com/" }); // HTML + base URL      — either engine
toPdf({ url: "https://example.com" }); // live URL             — chromium
toPdf({ file: "/abs/report.html" }); // local file           — chromium
toPdf({ element: domNode }); // DOM node             — canvas (browser)

Runtime support

RuntimeDefault engineNeeds
Node ≥ 18chromiumpuppeteer or playwright
Bunchromiumpuppeteer or playwright
Browsercanvasnothing (built in)

Force one with { engine: "chromium" } or { engine: "canvas" }; the default auto picks per runtime.

Without a bundler

A prebuilt UMD/IIFE global ships in the package and is served by the CDNs, so the browser needs no npm at all:

html
<!-- Global build → window.htmlpdfx -->
<script src="https://unpkg.com/htmlpdfx"></script>
<script>
  htmlpdfx
    .toPdf(document.getElementById("invoice"))
    .then((pdf) => pdf.download("invoice.pdf"));
</script>

<!-- …or ES modules straight from a CDN -->
<script type="module">
  import { toPdf } from "https://esm.sh/htmlpdfx";
</script>

Next

Released under the MIT License. Sponsor.