html-pdf-forge
v1.4.0 · stable·41 behavioral tests

HTML to PDF.
No Chromium.

A clean TypeScript wrapper over html-to-pdfmake and pdfmake. Templates, watermarks, QR codes, merge and split — wired into one ergonomic call.

install
106 MB
vs 300 MB Puppeteer
cold start
~ 240 ms
Lambda baseline
footprint
0 MB
of Chromium
Halberd & Folk · Q4 2025INV-0042

Q4 Reconciliation

Bill to Halberd & Folk Atelier
Wires due 14 days from issue · USD

Engineering retainer$ 4,200.00
System architecture$ 1,840.00
Type system audit$ 720.00
Total$ 6,760.00
Page 1 of 3
§02 · Feature surface

Everything you reach for, in one call.

The pipeline is small on purpose. The features that ship are the ones teams ask for again and again — wired in, typed end-to-end, and lazy where it matters.

options12 fields
  • page.size'A4'
  • watermark'DRAFT'
  • header(page) => …
  • pageNumber{ placement: 'footer' }
  • metadata.title'Q4 Report'
  • protect{ userPassword }
// deep-merged with defaults~106 KB pkg

Configure once, reuse everywhere

Per-call options deep-merge with stateful HtmlPdfForge defaults. Twelve fields, one ergonomic call.

<pdf-qr value="…" ec="M" />

QR codes that just embed

Drop <pdf-qr> into your HTML. Lazy-loaded — plain pages never pay the cost.

protect.userPassword

Watermarks & protection

Diagonal text watermarks, owner / user passwords, granular permission flags.

pdf-lib bridge
spreadmergedsplit
mergePdfs([a, b, c])splitPdf(buf, [[1,3],[4,6]])

Merge & split, deterministic

Combine PdfResults, Buffers, or file paths interchangeably. Extract page ranges with 1-indexed precision.

§03 · Compared

Trade pixel-perfect for predictable.

Reach for Puppeteer when you need flexbox, grid, or web fonts via @font-face URL. Reach for forge when you need fast, reproducible output and don't want a Chromium tax on every cold start.

Dimensionforgepdfmakepuppeteer
Headless browserChromium
Install footprint106 MB80 MB300 MB
API surface1 fnMulti-stepBrowser ctx
Output determinismYesYesPer browser

// Determinism wins for invoices, reports, contracts, anything that has to byte-match across runs.

§04 · Three lines

The smallest call you'll make all week.

No printer wiring, no stream plumbing, no jsdom boilerplate. Pass HTML, get a typed PdfResult with five output methods.

tsreport.ts
import { htmlToPdf } from '@rexymayderio/html-pdf-forge';

const pdf = await htmlToPdf(
  '<h1>Hello</h1><p>From html-pdf-forge.</p>',
);

await pdf.saveToFile('./hello.pdf');