Library / SDK
bpampuch/pdfmake avatar
bpampuch/pdfmake

pdfmake: Building PDFs from a JavaScript Document Definition

Client/server side PDF printing in pure JavaScript

12,350 stars2,078 forksJavaScriptNOASSERTION

At a glance

What is it?
pdfmake generates PDFs from a JSON-style document definition, in Node or in the browser. It fits structured, data-driven documents; it is the wrong tool when your layout already exists as HTML.
Who is it for?
Adopt pdfmake when your document is data first and layout second: invoices, reports, labels, anything you can express as an object tree with styles. Do not adopt it to convert an existing HTML page or CSS stylesheet into a PDF, because it has no HTML or CSS parser and you would be rewriting the layout.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 110 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What pdfmake solves, and for whom

Generating a PDF usually means one of two paths: drive a headless browser and print a page, or write low-level drawing calls that place text at coordinates. pdfmake sits in a third position. You describe the document as a JavaScript object, and the library lays it out. Line wrapping, text alignment, page breaks, repeated table headers and page numbering are handled by the layout engine rather than by you.

The README describes it as a "PDF document generation library for server-side and client-side in pure JavaScript", which is the practical dividing line. The same document definition can run in a Node process that writes a file, or in a browser tab that hands the user a download through the helper methods for opening, printing and downloading. The feature list is aimed at business documents: tables with auto, fixed and star-sized widths, col-spans and row-spans, headers repeated after a page break, snaking columns for newspaper-style flow, images and vector graphics, headers and footers with access to the current page number and page count, a table of contents, and PDF metadata such as author and subject.

Who it is for, concretely: a backend service that turns an order, a statement or a report into a file, and a frontend that needs to produce the same document without a server round trip. It is not for teams whose source of truth is an HTML template. There is no HTML parser in the dependency list; the dependencies are linebreak, pdfkit and xmldoc.

The document definition and how it reaches the PDF

The unit of work is a document definition object. You pass it to the library, which returns a PDF document object; on the server you then write it out, and in the browser you use the helper methods. The README does not spell out the full call signature in the text, but the examples directory is the reference: basics.js for the minimal case, styling_named_styles.js and styling_named_styles_with_extends.js for style inheritance, tables and columns in columns_simple.js, snaking_columns.js, lists.js, images.js, links.js, outlines.js, pageReference.js, background.js, margins.js, sections.js, absolute.js and relative.js, plus security.js, pdfa.js, qrCode.js, attachments.js and standardfonts.js.

The layering is worth understanding because it sets the limits. pdfmake depends on pdfkit for the actual PDF writing, on linebreak for text breaking, and on xmldoc, which is used when SVG content is involved. The build pipeline compiles the source into js/ for Node and build/pdfmake.js for the browser, and build:vfs and build:fonts steps bundle fonts into the browser build. That is why the browser build is heavier than a plain script: fonts travel with it.

Style inheritance is the part that rewards a little planning. Named styles can extend other named styles and be overridden per node, and the examples cover both extends and overrides. If you define a small style vocabulary up front (heading, body, tableHeader, footnote) and reuse it, the document definition stays readable as it grows. If you inline formatting on every node instead, the object tree becomes the maintenance problem.

Installing pdfmake and producing a first PDF

The package is published on npm as pdfmake. The package.json engines field requires Node 20 or newer, so check that before installing.

bash
npm install pdfmake

The README does not include a server-side usage snippet, but it points at the examples directory, where basics.js is the starting point. The repository's examples/ directory is where the document definition shape lives; the README itself only links to it.

For the browser, the package field browser points at build/pdfmake.js, and the README links a playground at bpampuch.github.io/pdfmake/playground.html where you can paste a document definition and see the result. That playground is the fastest way to check whether a layout idea is expressible before writing it into your codebase.

If you want to build the library from source rather than install it, the README gives the clone, install and build sequence:

bash
git clone https://github.com/bpampuch/pdfmake.git
cd pdfmake
npm install
npm run build

The yarn equivalent is documented as yarn followed by yarn run build. The build script runs a chain of steps: build:clean, build:node, build:browser, build:standard-fonts, build:fonts and build:vfs.

Where pdfmake stops being the right tool

The clearest boundary is HTML. pdfmake has no HTML or CSS parser. If your document already exists as a web page, adopting pdfmake means rebuilding that layout as a document definition, and the two will drift apart every time the page changes. Teams in that situation usually want a browser-based renderer instead.

The second boundary is fonts and the browser bundle. Font embedding is a listed feature, and the repository carries fonts/ and standard-fonts/ directories plus build:fonts and build:vfs steps. That means non-Latin scripts and custom typefaces require you to supply and register font files; the browser build carries them, which affects payload size. If your documents are mostly CJK or a licensed corporate typeface, budget time for font handling before you judge the library on a Latin-only test.

The third boundary is anything interactive or form-based. The feature list covers document composition, metadata, security and PDF/A output, but the README does not describe AcroForm field creation or JavaScript embedded in the PDF. If your requirement is a fillable form, verify that against the documentation before choosing pdfmake.

Finally, note the licence metadata. The repository's LICENSE file and the README both state MIT, while the repository's licence field is reported as NOASSERTION. The README's licence section is unambiguous, but if your organisation runs automated licence checks, resolve that discrepancy rather than assuming either side.

pdfmake against pdfkit, jsPDF and headless-browser printing

pdfkit is the closest comparison because pdfmake is built on it. pdfkit gives you a drawing API: you position text, draw lines, manage pages yourself. pdfmake gives you a layout engine on top, so wrapping, alignment, table widths and repeated headers are declarative. If you need precise control over where every element lands, pdfkit is the lower layer and you can reach it directly. If you want to describe a table and let something else decide the column widths, pdfmake is the abstraction you want.

jsPDF takes a different route. It is a client-side PDF writer with an imperative API and a long history of plugins for tables and autotables. The practical difference is the same one: with pdfmake you hand over a structure, with jsPDF you issue commands. Which one is less work depends on whether your content is naturally a tree or naturally a sequence of drawing operations.

Headless-browser printing, the puppeteer approach, inverts the whole problem. You keep the HTML and CSS you already have and let a real browser engine paginate it. You get CSS layout fidelity for free, and you pay for it with a browser process, a heavier deployment and slower generation. pdfmake produces the PDF inside your existing Node process with no browser, which matters when you generate thousands of documents in a queue.

react-pdf and html2pdf sit at other points on the same axis. react-pdf renders React components into PDF primitives, so it fits React codebases that want components rather than a plain object tree. html2pdf converts DOM content, which brings back the HTML fidelity question. pdfmake's answer is consistent across all of them: structured definition in, PDF out, no DOM involved.

Maintenance, release cadence and upgrade cost

The repository is not archived. The most recent push recorded is 2026-06-12, and the latest release in that window is 0.3.11, published the same day, following 0.3.10 on 2026-06-07 and 0.3.9 on 2026-05-23. That is a steady stream of patch releases rather than a frozen project.

The version number is the thing to plan around. At 0.3.x, the project has not declared a stable 1.0 API. Minor releases in a 0.x line are where breaking changes live, so pinning an exact version and reading CHANGELOG.md before each bump is the cheap habit here. The changelog is a top-level file in the repository, so it is the first place to look when a document definition that worked stops working.

Upgrade cost also depends on your build setup. pdfmake ships a Node entry (main points at js/index.js), an esnext entry (src/index.js) and a browser bundle (build/pdfmake.js). If you consume the browser bundle, the font and VFS build steps are part of what you are shipping, and a version bump can change that bundle's contents. If you consume it through a bundler, the devDependencies list shows webpack, babel and a source-map-loader, which is the toolchain the maintainers test against.

On licensing: the README states MIT, and the LICENSE file is in the repository root. The repository metadata field reads NOASSERTION, which typically means an automated classifier could not match the file to a known licence template. That is a metadata artefact rather than a licence change, but it is the kind of thing that trips a compliance gate, so check the LICENSE file itself rather than the badge.

Editorial conclusion

Adopt pdfmake when your document is data first and layout second: invoices, reports, labels, anything you can express as an object tree with styles. Do not adopt it to convert an existing HTML page or CSS stylesheet into a PDF, because it has no HTML or CSS parser and you would be rewriting the layout. Before committing, verify two things against your own environment: that your Node version satisfies the engines field, which requires Node 20 or newer, and that the fonts you intend to embed are actually present in the fonts and standard-fonts directories of the version you install.

Frequently asked questions

What is pdfmake?

It is a PDF document generation library in pure JavaScript that runs on the server and in the browser. You describe the document as an object and it handles layout, tables, page breaks, headers and footers.

How do I install pdfmake?

Install it from npm with npm install pdfmake. The package.json engines field requires Node 20 or newer, and the README also documents building from source with git clone, npm install and npm run build.

How do I use pdfmake?

You build a document definition with a content array and pass it to the library, which returns a PDF document object. The examples directory covers the pieces individually, and the README links a playground where you can try a definition in the browser.

How do I use pdfmake in Angular?

The repository material does not document an Angular integration, so there is no verified answer here. The library does ship a browser bundle at build/pdfmake.js and a playground, which is what a browser-side integration would start from.

Is pdfmake the same as pdfkit?

No. pdfmake depends on pdfkit and adds a layout layer on top of it, so you describe a document structure instead of issuing drawing commands. pdfkit gives you direct control over positioning; pdfmake handles wrapping, table sizing and repeated headers for you.

Official sources

  1. bpampuch/pdfmake on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/bpampuch-pdfmake.svg)](https://hysenlabs.com/projects/bpampuch-pdfmake)