pdf-engineHTML to PDF in your browser

Edit the HTML, get a real PDF. It is made here, in your browser, by WebAssembly: no server, no Chromium, nothing uploaded.
Loading the engine…
More options page size, orientation, compression, password, workers, speed test
Options Sizes accept in, mm, cm, pt, px.
Speed test Makes the current example again and again, with different numbers each time, and times it. Nothing is uploaded.
The template language is minijinja: {{ value }}, {% for %}, {% if %}, {% include "partial" %}. Use <img src="logo"> for the logo above.
The PDF appears here

HTML to PDF in the browser, with no server and no Chromium

pdf-engine is a free, open-source (MIT) HTML to PDF generator written in Rust and compiled to WebAssembly. It turns an HTML template and your data into a real PDF with selectable vector text, entirely on the user's own device: no backend, no headless Chrome, no Puppeteer, nothing uploaded. The same engine runs in Node.js, Electron, Tauri and Docker, and can print receipts and labels (ESC/POS, ZPL).

What you get

Install

npm install @lands-horizon-corp/pdf-engine-wasm
import { PDFEngine } from '@lands-horizon-corp/pdf-engine-wasm';

const pdf = new PDFEngine();
await pdf.download({
  template: '<h1>Invoice {{ no }}</h1>',
  data: { no: '12345' },
}, 'invoice.pdf');

No bundler? Import it from a CDN: https://cdn.jsdelivr.net/npm/@lands-horizon-corp/pdf-engine-wasm@1/index.js

How it compares

pdf-enginedompdf.jsironpresshtml2pdf.js
Receipt, in the browser1.3 ms2.8 ms39 ms86 ms
Text is real textyesyesyesno (a picture)
Download (compressed)3.3 MB0.17 MB4.7 MB0.26 MB
Math and Markdown built inyesnoyesno
Receipt and label printingyesnonono

Chromium on an Apple M4, median after warm-up. dompdf.js starts faster and downloads less; Puppeteer renders any web page, including JavaScript, which pdf-engine does not run. The full benchmark and its methods are in the repository.

Frequently asked questions

Does pdf-engine need a server?

No. The browser build runs entirely in the page with WebAssembly, so the document is never uploaded and it works offline. The same engine also runs natively in Node.js, Electron, Tauri and Docker when you want a server.

Is it a replacement for Puppeteer or headless Chrome?

For documents built from HTML templates (invoices, receipts, reports, labels, certificates), yes: it needs no browser and makes a receipt in about a millisecond. It does not run JavaScript in the page and supports a subset of CSS (no float yet), so a page that depends on scripts or on every CSS feature still needs a real browser.

Does it work in Node.js?

Yes. The same package runs under Node.js (documents can be made in worker threads), and a native Node and Electron package talks to the Rust engine over stdin and stdout and can print to receipt and label printers.

Is the text real text or a picture?

Real vector text that can be selected, searched and copied, in small files. Libraries that screenshot the page (html2pdf.js, jspdf-html2canvas) produce pictures of text.

Can it do Markdown, math and QR codes?

Yes. Markdown with a filter, LaTeX formulas in math tags, and QR codes and barcodes as vector shapes, all built in, with no extra libraries to ship.

How fast is it?

About 1.3 ms for a receipt and 3 ms for a 30-line invoice in the browser (Chromium on an Apple M4). Ten thousand receipts take about 13 seconds as WebAssembly and about 4 seconds natively. dompdf.js starts faster and downloads less (0.17 MB against 3.3 MB); pdf-engine makes each document two to two and a half times faster once running. The benchmark, with every library and its methods, is in the repository.

Which license?

MIT. It is free for commercial use.