Skip to content
Guide

Architecture

htmlpdfx is intentionally small and layered. The core has zero runtime dependencies — both the PDF writer and the DOM rasterizer are written from scratch and live in the package.

The render pipeline

Every render walks the same path. Only the middle step branches:

toPdf(input, options)

normalizeOptions

One canonical, unit-free config — everything resolved to mm internally.

resolveInput

Works out what you passed: an HTML string, a URL, a file, or a live DOM node.

selectEngine

auto resolves to chromium on the server and canvas in the browser.

chromium engine

Node · Bun · Deno

  • Launch or reuse a browser via puppeteer / playwright
  • page.pdf() — vector text, real CSS
  • Native CSS page breaks and @page

canvas engine

Browser

  • renderDomToImage — SVG foreignObject
  • computePageSlices — break-aware slicing
  • PdfWriter — our own PDF writer

PdfResult

bytes · pageCount · engine · save() · download() · toBlob() · toDataUrl()

Why not jsPDF + html2canvas?

Those libraries rasterize HTML into a single image, which is the root cause of most of their bugs: non-selectable text, blank pages past the canvas size limit, ignored page breaks, dropped modern CSS. htmlpdfx instead:

  • uses a real browser when one is available (vector output, real CSS); and
  • in the browser, ships its own renderer + PDF writer so there are no heavy peer dependencies to install, mismatch, or break on new CSS features.

Modules

ModuleResponsibility
core/options.tsNormalize options → canonical mm-based config
core/pagesize.tsPaper sizes + orientation
core/paginate.tsPage-break-aware slicing (pure, fully tested)
core/css.tsInjected @page + break-* + color-adjust CSS
core/template.tsHeader/footer token expansion
pdf/writer.tsDependency-free PDF writer (images, text, metadata)
dom/rasterize.tsDOM → image via SVG foreignObject (browser)
engine/chromium.tsPuppeteer/Playwright engine
engine/canvas.tsBuilt-in browser engine

Building blocks are exported

Advanced users can use the primitives directly:

ts
import { PdfWriter, renderDomToImage, computePageSlices } from "htmlpdfx";

Released under the MIT License. Sponsor.