pdfmake
pdfmake is a JavaScript library for generating PDF documents on both client and server sides. It is currently at version 0.3.7 and maintains an active release cadence, with multiple minor updates released recently addressing features, fixes, and security patches. Key features include advanced text layout with line-wrapping and alignments, support for bulleted and numbered lists, comprehensive table layouts with features like col-spans, row-spans, and repeating headers, and the new snaking columns for newspaper-style content. It also handles images, vector graphics, and provides a powerful styling system with inheritance. The library supports dynamic page headers/footers, background layers, custom page breaks, and outlines/bookmarks for generated PDFs. Differentiating itself through its pure JavaScript implementation, pdfmake provides a unified, promise-based interface for both Node.js and browser environments, simplifying PDF generation workflows across different platforms.
Common errors
-
ReferenceError: require is not defined
cause Attempting to use CommonJS `require()` syntax in an ES Module context after pdfmake v0.3.0 transitioned to ES6+.fixChange your import statements to use ES Modules syntax: `import * as pdfMake from 'pdfmake/build/pdfmake';`. -
TypeError: pdfMake.createPdf(...).getBuffer is not a function (or similar 'callback is not a function')
cause Using the old callback-based API (`getBuffer((buffer) => {})`) with pdfmake versions 0.3.0 or higher, which now use a promise-based API.fixUpdate your code to use the promise-based API: `const pdfDoc = pdfMake.createPdf(docDefinition); const buffer = await pdfDoc.getBuffer();` or `pdfDoc.getBuffer().then(buffer => ...);`. -
Error: SVG must have width and height specified
cause An SVG image in the document definition is missing explicit `width` and `height` attributes, which are now strictly validated.fixEnsure all SVG strings or `svg` nodes in your document definition include defined `width` and `height` properties. -
Error: Unauthorized URL access: [URL]
cause Attempting to use an external URL for an image or resource without configuring a URL access policy after the v0.3.6 update.fixSet a URL access policy using `pdfMake.setUrlAccessPolicy((url) => url.startsWith('https://your-allowed-domain.com/'));` before creating the PDF, allowing only trusted URLs.
Warnings
- breaking Version 0.3.0 introduced significant breaking changes, including dropping support for Internet Explorer 11, requiring Node.js 20 LTS or newer, porting the codebase to ES6+, unifying the interface for Node.js and browser, and changing all methods to return Promises instead of using callbacks.
- breaking The way virtual font storage is included, especially on the client-side, changed significantly in v0.3.0. This can affect how fonts are loaded and made available to pdfmake.
- gotcha A potential server vulnerability (CVE-2026-26801) was addressed in v0.3.6. For security reasons, pdfmake now requires defining a custom URL access policy using `pdfMake.setUrlAccessPolicy()` for any external URLs (e.g., for images) before they can be downloaded and used in PDFs.
- gotcha SVG validation was enhanced in versions 0.2.23 and 0.3.2. SVG elements used in your document definition must explicitly specify `width` and `height` properties, either within the SVG string/element itself or in the `svg` node properties.
Install
-
npm install pdfmake -
yarn add pdfmake -
pnpm add pdfmake
Imports
- pdfMake
const pdfMake = require('pdfmake');import * as pdfMake from 'pdfmake/build/pdfmake';
- pdfFonts
import { vfs_fonts } from 'pdfmake';import * as pdfFonts from 'pdfmake/build/vfs_fonts';
- setUrlAccessPolicy
pdfMake.setUrlAccessPolicy((url) => { /* ... */ });
Quickstart
import * as pdfMake from 'pdfmake/build/pdfmake';
import * as pdfFonts from 'pdfmake/build/vfs_fonts';
import * as fs from 'fs'; // For Node.js file system operations
// Assign fonts (crucial for pdfmake to work)
pdfMake.vfs = pdfFonts.pdfMake.vfs;
// Define an optional URL access policy for external images/resources
// This is critical since v0.3.6 (CVE-2026-26801 fix)
pdfMake.setUrlAccessPolicy((url) => {
// Only allow access to URLs from example.com
return url.startsWith("https://example.com/");
});
const docDefinition = {
content: [
{ text: 'Hello, pdfmake!', style: 'header' },
'This is an example PDF generated using pdfmake version 0.3.7.',
{ text: 'Features showcased:', margin: [0, 15, 0, 5] },
{
ul: [
'Structured content with text and lists.',
'Basic styling with custom font sizes and bold text.',
'Uses the modern promise-based API for generation.'
]
},
{ text: 'A small table:', style: 'subheader', margin: [0, 15, 0, 5] },
{
table: {
headerRows: 1,
widths: ['*', 'auto', 100],
body: [
['Column 1', 'Column 2', 'Column 3'],
['One value', 'Another value', 'Some more text'],
[{ text: 'Complex cell with span', colSpan: 2 }, {}, 'Last cell']
]
}
}
],
styles: {
header: { fontSize: 22, bold: true, alignment: 'center', margin: [0, 0, 0, 20] },
subheader: { fontSize: 16, bold: true }
},
defaultStyle: {
font: 'Roboto' // Ensure a font is available, Roboto is default via vfs_fonts
}
};
async function generatePdf() {
try {
const pdfDoc = pdfMake.createPdf(docDefinition);
const buffer = await pdfDoc.getBuffer();
fs.writeFileSync('output.pdf', buffer);
console.log('PDF generated successfully: output.pdf');
} catch (error) {
console.error('Error generating PDF:', error);
}
}
generatePdf();