Modern, high-performance browser-native paginated document rendering.
Printedjs is a modular TypeScript redesign of legacy Paged.js, engineered for high reliability, deterministic lifecycle control, zero core DOM dependencies, and resilient edge-case handling.
Printedjs is maintained as a modular pnpm monorepo with clean architectural boundaries:
@printedjs/core— Zero DOM/CSSOM pagination runtime, pure contracts, CSS AST facade, and progress-guarded state machines@printedjs/browser— Browser renderer supportingrootcontainer andiframesurfaces, layout measurement, and page virtualization@printedjs/plugins— Standard preset, core layout plugins, and community extensions (see available plugins)
@printedjs/minimal— Standalone bundle (printedjs.min.js) with complete engine, plugins, auto-init, and legacy Paged.js migration shims@printedjs/polyfill— Compatibility layer for older browsers, providing DOM and observer polyfills@printedjs/cli— Headless PDF generation CLI (printedjs render) with Playwright and Puppeteer drivers@printedjs/devtools— Diagnostic trace collector and non-layout visual inspector overlay
apps/playground— Interactive developer fixture playground with surface and diagnostics toggles (pnpm dev)apps/minimal-demo— Zero-config standalone demo showcasing static HTML document pagination using@printedjs/minimal(pnpm dev:minimal)
All core plugins can be loaded together via @printedjs/plugin-preset or installed individually for fine-grained tree-shaking:
@printedjs/plugin-page-rules—@pagesize, margins, orientation, bleeds, and crop marks@printedjs/plugin-breaks— CSSbreak-before,break-after,break-inside, and avoid rules@printedjs/plugin-strings— Named strings (string-set,string()) for running headers and footers@printedjs/plugin-generated-content— 16 W3C margin boxes, track distribution, and running elements@printedjs/plugin-counters— Page numbering (counter(page),counter(pages)), Roman/alpha styles, andtarget-counter@printedjs/plugin-footnotes— W3C GCPMfloat: footnote,@footnotearea, and continuation slicing@printedjs/plugin-columns— Multi-column layout (column-count,column-gap,column-span: all, balancing)@printedjs/plugin-widows-orphans— Typography constraints at page boundaries (widows,orphans)@printedjs/plugin-math— Formula break protection for KaTeX, MathJax, and MathML@printedjs/plugin-hyphenation— Soft hyphen preservation and hyphenation normalization@printedjs/plugin-bookmarks— Document heading hierarchy extraction and PDF bookmark outline@printedjs/plugin-lists— Ordered list numbering and sequence continuity across page splits@printedjs/plugin-running-headers— Dynamic running headers and footers utility alias@printedjs/plugin-views— Presentation view modes (single page, spread)@printedjs/plugin-preset— Standard bundle combining all core layout plugins
@printedjs/plugin-page-flip— Interactive 3D flipbook page-turning presentation engine@printedjs/plugin-eta— Dynamic pre-pagination document templating powered by Eta
pnpm add @printedjs/browser @printedjs/pluginsimport { createRenderer } from "@printedjs/browser";
import { standardPreset } from "@printedjs/plugins";
const target = document.querySelector("#output")!;
const renderer = createRenderer({
target,
isolation: "root", // or "iframe" for total style & script sandboxing
plugins: standardPreset(),
});
const result = await renderer.render({
content: {
html: `
<style>
@page {
size: letter;
margin: 1in;
@bottom-center {
content: counter(page);
}
}
</style>
<h1>Document Title</h1>
<p>Content flows cleanly across page boundaries.</p>
`,
},
});
console.log(`Rendered ${result.pages.length} pages.`);
// Clean up completely with zero DOM residue:
renderer.destroy();# Render HTML document to PDF with print bleed and A4 format (Playwright or Puppeteer)
pnpm printedjs render document.html -o document.pdf --format A4 --bleed 3mm --engine playwright
pnpm printedjs render document.html -o document.pdf --format A4 --engine puppeteer
# Live watch mode for iterative document authoring
pnpm printedjs render document.html -o document.pdf --watch| Feature / Capability | Printedjs | Paged.js |
|---|---|---|
CSS @page Rules (sheet sizes, margins, bleed, crop marks) |
✅ | ✅ |
| CSS Margin Boxes (16 standard margin boxes) | ✅ | ✅ |
Page Counters & Styles (roman, alpha, counter(pages), target-counter) |
✅ | ✅ |
Named Strings (string-set, running headers & footers) |
✅ | ✅ |
Standard Page Breaks (break-before, break-after, avoid) |
✅ | ✅ |
Drop-in <script> Polyfill (auto-render on page load) |
✅ | ✅ |
| Cross-Browser Engine Parity (Chromium, Firefox, WebKit) | ✅ | |
Physical Blank Page Insertion (recto / verso spreads) |
✅ | |
Table Header & Footer Repeating (<thead> / <tfoot>) |
✅ | |
Multi-Column Formatting (column-count, balancing) |
✅ | |
Footnote Layout (float: footnote, continuations) |
✅ | |
| Cross-Page Table Column Width Synchronization | ✅ | ❌ |
Multi-Page Table rowspan Continuation |
✅ | ❌ |
| Math Formula Break Protection (KaTeX, MathJax, MathML) | ✅ | ❌ |
Infinite Loop & Freeze Guard (LayoutProgressGuard) |
✅ | ❌ |
DOM Isolation Surfaces (in-place root or sandboxed iframe) |
✅ | ❌ |
Clean Teardown (deterministic destroy(), zero DOM residue) |
✅ | ❌ |
| Pure Zero-DOM Core (headless Node / Worker execution) | ✅ | ❌ |
| Page Virtualization (smooth scrolling on 200+ pages) | ✅ | ❌ |
Incremental Re-Pagination (renderIncremental) |
✅ | ❌ |
| 100% Strict TypeScript (strict types & exported contracts) | ✅ | ❌ |
| Native Headless PDF CLI (Playwright & Puppeteer drivers) | ✅ | ❌ |
Legend: ✅ Full Support |
Printedjs delivers a significantly leaner footprint than legacy Paged.js, with tree-shakable modular packages for modern bundlers:
| Distribution / Bundle | Minified | Gzip | Brotli | vs Paged.js |
|---|---|---|---|---|
Paged.js Polyfill (paged.polyfill.min.js) |
504.1 KB | 99.0 KB | 83.6 KB | Baseline |
Printedjs Standalone Bundle (@printedjs/minimal) |
200.1 KB | 52.2 KB | 44.9 KB | -60.3% |
Printedjs Browser Renderer (@printedjs/browser) |
105.2 KB | 19.4 KB | 16.7 KB | Modular import |
Printedjs Core Engine (@printedjs/core) |
18.2 KB | 4.6 KB | 4.1 KB | Pure zero-DOM |
- Documentation Hub
- Architecture & Design Principles
- Package Catalog & Overview
- Migrating from Paged.js
- Plugin Authoring Guide
- Headless PDF CLI
- Release Readiness & Packaging
- Project Roadmap
# Verify code formatting, linting, typechecks, and unit test suite
pnpm verify
# Build all packages and applications
pnpm build
# Run browser tests across engines (Chromium, Firefox, WebKit)
pnpm test:browser
# Validate distribution package exports and bundles
pnpm pack:checkPrintedjs is rigorously validated against the 122-fixture legacy Paged.js corpus located in tests/fixtures/, with verified accepted baselines in tests/baseline/accepted/.
Printedjs is inspired by and builds upon the pioneering work of Paged.js by the Cabbage Tree Labs community. We are deeply grateful to the Paged.js authors and contributors for championing CSS Paged Media standards in browsers and providing the foundational groundwork that made this project possible.