pdfmake

Generate PDF documents from a declarative JSON definition, in Node.js or the browser

Library
npm
v0.3.11
12,332stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
76/100Good
Development Activity48
Maintenance72
Community84
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
71/100Good
Architecture78
Code Quality74
Innovation68
Learning Curve65

pdfmake is a pure-JavaScript PDF generation library that lets applications describe a document — text, tables, columns, images, lists, headers/footers, page breaks — as a plain JSON document-definition object, then renders it to a PDF either on the server (Node.js) or directly in the browser, using the same document-definition format and rendering pipeline in both environments. Built on top of pdfkit for low-level PDF primitives, it adds a full layout engine handling line-wrapping, auto/fixed/star-sized table columns, row/col-spans, repeating table headers across page breaks, snaking (newspaper-style) columns, and style inheritance.

It ships helper methods for opening, downloading, or printing a generated PDF directly from browser code, along with font-embedding support and a hosted playground for experimenting with document definitions interactively. With over 12,000 GitHub stars and 2M+ weekly npm downloads, it’s one of the most widely used JavaScript PDF-generation libraries for invoices, reports, and other structured documents.

What You Get

  • A declarative JSON document-definition format describing text, tables, columns, images, and layout
  • A full table layout engine: auto/fixed/star-sized widths, col/row-spans, repeating headers, snaking columns
  • Identical rendering pipeline usable server-side (Node.js) or client-side (browser) from the same document definition
  • Font embedding and custom font support beyond the bundled standard fonts
  • Browser helper methods (open, download, print) for delivering generated PDFs directly to users

Common Use Cases

  • Generating invoices, receipts, and financial reports server-side from application data
  • Letting end users export a report or document to PDF directly in the browser without a server round-trip
  • Producing multi-page documents with repeating table headers, page numbers, and dynamic headers/footers
  • Building printable, structured business documents (contracts, certificates, tickets) from templated JSON definitions

Under The Hood

Architecture - src/index.js wires together a pipeline of dedicated classes: DocPreprocessor normalizes the raw document-definition object, LayoutBuilder walks it to compute measured lines/pages via TextInlines, TableProcessor/columnCalculator, and DocumentContext, and ElementWriter/Renderer emit the final drawing calls onto a pdfkit document; OutputDocument/OutputDocumentServer split server-only output paths (streams, buffers) from the shared browser/server core, and virtual-fs.js provides an in-memory filesystem abstraction so the same font/asset-loading code works in both environments.

Tech Stack - Pure JavaScript (~8,000 lines across src/) built on pdfkit for low-level PDF primitives plus linebreak for Unicode-aware line breaking and xmldoc for parsing embedded SVG/XML content; Babel compiles the ESM source to both a Node.js CommonJS build (js/) and a bundled browser build (build/pdfmake.js) from the same src/ tree, which is what enables the isomorphic API.

Code Quality - tests/unit (20 files) covers layout primitives (line-wrapping, table/column calculation, style inheritance) with Mocha, tests/integration compares rendered PDFs against fixtures, and tests/browser exercises the browser bundle specifically; ESLint with eslint-plugin-jsdoc enforces documented public APIs across the large layout-engine codebase.

API Design - The single-entry-point createPdf(docDefinition) call and declarative JSON document format keep the common case simple (pass an object, get a PDF), and the same definitions work unchanged between Node and browser; the tradeoff is that achieving precise layouts (nested tables, multi-column flows, custom fonts) requires learning pdfmake’s own JSON schema rather than an imperative drawing API, which raises the ceiling but not the floor of the learning curve.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search