Top JavaScript PDF generator libraries for 2026
Table of contents
Templates, merging, and watermarking through Nutrient DWS — start with 50 free credits.
Choose a JavaScript PDF generator by its input and runtime. Use PDFKit for programmatic Node.js documents, jsPDF for browser downloads, pdfmake for declarative layouts, pdf-lib for modifying existing PDFs, and Puppeteer for HTML/CSS conversion. Nutrient Web SDK combines document operations with an interactive viewer; Nutrient’s server products cover backend processing.
Choose by document input and runtime
The libraries solve different problems. A tool that draws text into a new PDF isn’t necessarily an HTML renderer or an editor for existing page content.
| Tool | Typical input and use | Runtime | License |
|---|---|---|---|
| PDFKit | Programmatic text, graphics, reports, and invoices | Node.js; browser builds available | MIT |
| jsPDF | Programmatic browser documents; optional HTML conversion | Browser and Node.js | MIT |
| pdf-lib | Existing PDFs, form templates, merging, and new pages | Browser and Node.js | MIT |
| pdfmake | Declarative text, tables, styles, and page layout | Browser and Node.js | MIT |
| Puppeteer | HTML and CSS rendered by Chrome | Node.js controlling a browser | Apache 2.0 |
| Nutrient Web SDK | Interactive document operations, PDF templates, and image-to-PDF export | Browser; separate Nutrient products for backend processing | Commercial |
The examples below use Node.js 22.12 or later and pinned package versions. Browser examples should be served over HTTP. Installation commands assume separate example projects; keep production dependency updates and security review part of your maintenance process.
1. Nutrient Web SDK: Enterprise JavaScript PDF generator and viewer

Nutrient Web SDK is a commercial JavaScript library for viewing and working with documents in the browser. It supports PDF templates, image-to-PDF export, annotations, and forms. Features depend on licensing and deployment configuration.
PDF generation capabilities
- Create from template — Populate a PDF template or use the separate Word-template generation workflow; check the applicable component requirements.
- Generate from images — Convert JPG, PNG, or TIFF files into PDF documents.
- Thumbnail previews — Render PDF pages as thumbnail images for gallery or navigation UIs.
- Saving options — Export your generated PDFs to an
ArrayBufferor browser storage, or upload to a remote server. - Headless operation — Run document operations without displaying a UI in the browser. This mode doesn’t turn Web SDK into a Node.js server library.
- Extendable — Add form filling, electronic signatures, annotation, and collaboration with the required product configuration.
When to use Nutrient Web SDK as your JavaScript PDF generator
- Enterprise applications needing PDF generation workflows (invoices, reports, contracts)
- Scenarios combining generation with interactive editing, annotation, and real-time collaboration in the browser
- Browser applications integrating with a separate server-side document-processing service
- Projects that need well-documented APIs and commercial support
- Teams seeking an integrated solution for both generation and document interactions
Getting started with Nutrient Web SDK
Install the package and self-host the matching runtime assets. The archive supplies the resources loaded by the JavaScript entry point:
npm init -ynpm install @nutrient-sdk/viewer@1.21.0mkdir -p assetscp node_modules/@nutrient-sdk/viewer/dist/nutrient-viewer.js assets/curl -fL https://cdn.cloud.nutrient.io/assets/pspdfkit-web-assets@1.21.0.zip -o assets.zipunzip -q assets.zip -d assetsPreserve the archive’s directory structure, including nutrient-viewer-lib/. See the self-hosting guide for deployment options. Without a license key, the example runs in trial mode.
Integrating into your project
- Add the PDF document you want to display (e.g.
example.pdf) to the root of your project. You can use our demo document as an example. - Create your HTML file (e.g.
index.html) with a viewer container and a download button:
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <title>Nutrient PDF Generator Example</title> <script src="assets/nutrient-viewer.js"></script> </head> <body> <!-- Download button. --> <button id="download-btn" disabled>Download PDF</button> <p id="status" role="status">Loading PDF…</p> <!-- PDF viewer mount point. --> <div id="nutrient" style="width:100%; height:80vh;"></div> <script src="index.js"></script> </body></html>In your main JavaScript file (e.g.
index.js), load the viewer using the globalwindow.NutrientViewerAPI:const downloadButton = document.getElementById("download-btn");const status = document.getElementById("status");let instance;async function loadPdf() {const response = await fetch("example.pdf");if (!response.ok) throw new Error(`PDF request failed: ${response.status}`);return NutrientViewer.load({container: "#nutrient",document: await response.arrayBuffer(),baseUrl: new URL("assets/", window.location.href).href,});}loadPdf().then((loadedInstance) => {instance = loadedInstance;downloadButton.disabled = false;status.textContent = "PDF ready.";}).catch((error) => {console.error(error);status.textContent = "Could not load the PDF. Check its URL and SDK assets.";});downloadButton.addEventListener("click", async () => {if (!instance) return;downloadButton.disabled = true;try {const buffer = await instance.exportPDF();const url = URL.createObjectURL(new Blob([buffer], { type: "application/pdf" }));const link = document.createElement("a");link.href = url;link.download = "download.pdf";document.body.append(link);link.click();link.remove();setTimeout(() => URL.revokeObjectURL(url), 60000);status.textContent = "PDF exported.";} catch (error) {console.error(error);status.textContent = "Export failed. Try again.";} finally {downloadButton.disabled = false;}});
Clicking Download PDF exports the loaded PDF, including supported edits, and triggers a browser download. This demonstrates exporting an existing document, not composing an invoice from HTML. Use the PDF template guide or image conversion guide for those inputs.
Run the project
Use a static file server like serve to launch your site locally:
npx serve . -l 3000Navigate to http://localhost:3000 to view the website.
Related reading:
- Automate your document creation with a PDF generator
- Node.js PDF generator: How to generate PDFs from HTML with Node.js
- How to export to PDF using React
- How to generate PDF event tickets
- How to generate PDF invoices from HTML in Java
- How to build a PowerPoint (PPT/PPTX) viewer in JavaScript
- How to open Excel (XLS and XLSX) files in the browser with JavaScript
- How to build a React.js file viewer: PDF, image, MS Office
- How to open Word (DOC and DOCX) files in the browser with JavaScript
Additional Nutrient PDF generation tools
For backend processing, evaluate the Nutrient Node.js SDK, Document Engine, or PDF generation API according to your input formats and hosting requirements. Web SDK’s browser headless mode and these server products are different deployment options.
For native apps, the same generation capability ships in the .NET, iOS, Android, React Native, Flutter, and MAUI SDKs.
2. PDFKit: A Node.js JavaScript PDF generator
PDFKit(opens in a new tab) is a Node.js library for creating multipage PDFs from scratch — text, images, shapes, and custom fonts. Browser integration is also available; follow the PDFKit setup documentation(opens in a new tab) for the installed release.
Key PDF generation features
- Create PDFs programmatically in JavaScript (Node.js environment)
- Embed images, vector shapes, and custom fonts
- Stream output to file, HTTP response, or buffer
- Use the browser build with the assets and font setup required by its version
When to use PDFKit as your JavaScript PDF generator
- Server-side invoice/report generation in Node.js
- Complex layout generation where you need full control via code
- Streaming PDFs directly to clients (e.g. on-demand PDF downloads)
Getting started with PDFKit
Initialize a new project and create an entry file (e.g.
app.cjs):Terminal window mkdir my-pdfkit-appcd my-pdfkit-appnpm init -ytouch app.cjsInstall PDFKit via
npm:Terminal window npm install pdfkit@0.20.2Create a PDF in
app.cjs:const { PDFDocument } = require("pdfkit");const { createWriteStream } = require("node:fs");const { pipeline } = require("node:stream/promises");async function createPdf() {const doc = new PDFDocument();const written = pipeline(doc, createWriteStream("output.pdf"));doc.text("Hello, PDFKit!");doc.end();await written;}createPdf().catch((error) => {console.error(error);process.exitCode = 1;});Run the script using Node.js to generate your PDF:
Terminal window node app.cjsCheck your directory for the
output.pdffile.
Related reading:
- Python HTML to PDF: Convert HTML to PDF using wkhtmltopdf
- Generate PDF invoices with PDFKit in Node.js
3. jsPDF: Browser-based JavaScript PDF generator

jsPDF(opens in a new tab) is a lightweight browser-side JavaScript PDF generator. It creates PDFs in the client from HTML content or JavaScript API calls. It also ships a Node.js build that works without additional setup.
Key PDF generation features
- Create PDFs directly in the browser (client-side) without server roundtrips
- Add text, images, shapes, and annotations via a simple API
- Generate PDFs from HTML content using plugins (e.g.
html2canvasintegration) - Plugin ecosystem for extended capabilities (tables, auto-pagination, custom fonts)
When to use jsPDF as your JavaScript PDF generator
- Client-side form submissions: Generate and download PDFs in the browser immediately
- Simple reports or invoices from web forms without hitting the server
- Use cases where low bundle size and minimal setup are priorities
- Quick prototyping of PDF output in frontend projects
Getting started with jsPDF
Install jsPDF via
npm:Terminal window npm install jspdf@4.2.1Add a basic HTML file to use
jsPDFin the browser:<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>jsPDF Example</title></head><body><button id="generate-pdf">Generate PDF</button><script src="node_modules/jspdf/dist/jspdf.umd.min.js"></script><script>const { jsPDF } = window.jspdf;document.getElementById("generate-pdf").addEventListener("click", function () {const doc = new jsPDF();doc.text("Hello, jsPDF!", 10, 10);doc.save("output.pdf");});</script></body></html>
Serve the project with npx serve . -l 3000, open http://localhost:3000, and click Generate PDF. It creates and downloads a PDF.
Related reading:
- How to convert HTML to PDF in React
- Generate PDFs in Salesforce with Lightning web components
- Generate a PDF from HTML with Vue.js
- How to use jsPDF and Angular to generate PDFs
- How to export to PDF using React
4. pdf-lib: JavaScript PDF generator and modifier
pdf-lib(opens in a new tab) is a JavaScript library for creating and modifying PDFs in both browser and Node.js environments. It handles generation from scratch and editing existing PDFs — filling forms, merging pages, and drawing additional content. It doesn’t provide a browser viewer or a general existing-text editor.
Key PDF generation features
- Create new PDFs with pages, text, images, and vector graphics
- Embed custom fonts and images
- Fill and modify existing PDF forms and structure
- Merge or split documents programmatically
- Runs in browsers and Node.js; custom font embedding needs the optional
fontkitintegration
When to use pdf-lib as your JavaScript PDF generator
- Applications needing both generation and modification of PDFs
- Filling out or programmatically editing existing PDF templates
- Merging multiple PDFs or adding dynamic content to an existing document
- Environments where a single library for both client-side and server-side use is ideal
Getting started with pdf-lib
Install the library via
npm:Terminal window npm install pdf-lib@1.17.1In
app.cjs, generate a PDF:const { PDFDocument, rgb, StandardFonts } = require("pdf-lib");const fs = require("fs");async function createPdf() {const pdfDoc = await PDFDocument.create();const page = pdfDoc.addPage([600, 400]);const font = await pdfDoc.embedFont(StandardFonts.HelveticaBold);page.drawText("Hello, PDF-lib JavaScript PDF generator!", {x: 50,y: 350,size: 18,font,color: rgb(0, 0, 0.8),});const pdfBytes = await pdfDoc.save();fs.writeFileSync("output.pdf", pdfBytes);}createPdf().catch((error) => {console.error(error);process.exitCode = 1;});Run your script to generate the PDF:
Terminal window node app.cjs
Related reading:
- How to build a JavaScript PDF editor with pdf-lib
- How to add annotations to PDF using Vue.js
- How to build a Node.js PDF editor with pdf-lib
- How to use JavaScript to capture signatures in PDFs
- How to convert images to PDF in Node.js
- How to fill a PDF form in React
- How to fill PDF forms in Node.js
- How to programmatically create and fill PDF forms in Angular
5. pdfmake: Declarative JavaScript PDF generator

pdfmake(opens in a new tab) is a declarative JavaScript PDF generator that works in both the browser and Node.js. You define the document structure via a JSON-like “document definition” object, and pdfmake handles layout, pagination, and styling.
Key PDF generation features
- Declarative document definitions (content arrays, styles, tables, lists)
- Built-in support for text styling, tables, lists, images, headers/footers
- Automatic pagination and page breaks based on content
- Embed custom fonts; validate font glyph coverage and complex-script layout with representative text
- Browser and Node.js support; initialization and output APIs depend on the release
When to use pdfmake as your JavaScript PDF generator
- Generating structured reports, invoices, and catalogs where layout is defined declaratively
- Projects where automatic pagination and complex layouts (tables, lists) are needed without manual page management
- Applications requiring rich text styling, headers/footers, and consistent formatting
- Situations where a JSON-based definition simplifies maintenance
Getting started with pdfmake
Install pdfmake via
npm:Terminal window npm install pdfmake@0.3.11Use
pdfmakein the browser with the following HTML file:<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>pdfmake Example</title></head><body><button id="generate-pdf">Generate PDF</button><script src="node_modules/pdfmake/build/pdfmake.min.js"></script><script src="node_modules/pdfmake/build/vfs_fonts.js"></script><script>document.getElementById("generate-pdf").addEventListener("click", function () {const docDefinition = { content: "Hello, pdfmake!" };pdfMake.createPdf(docDefinition).download("output.pdf").catch(console.error);});</script></body></html>Serve this project with
npx serve . -l 3000, openhttp://localhost:3000, and click Generate PDF to download a PDF.
Related reading:
6. Puppeteer: Headless Chrome JavaScript PDF generator

Puppeteer(opens in a new tab) is a Node.js library that controls headless Chrome/Chromium, often used to generate PDFs from webpages or dynamic HTML content. Use it when HTML and CSS are the source of the document. Print styles, page breaks, fonts, and browser versions affect the output.
Key PDF generation features
- Render a webpage to PDF; use print CSS to hide sections you don’t want in the output
- Support for CSS, web fonts, and complex layouts (flex, grid)
- Control page settings: margins, format, headers/footers, print styles
- Automate PDF generation in batch or on demand from dynamic content
When to use Puppeteer as your JavaScript PDF generator
- Generating PDFs from complex HTML/CSS where the layout must match browser rendering
- Server-side snapshotting of webpages or dynamic reports (dashboards, charts)
- Situations requiring accurate print preview rendering (e.g. invoices styled via CSS)
- Automated workflows or testing pipelines that output PDFs from live pages
Getting started with Puppeteer
Create a new directory and initialize your Node.js project:
Terminal window mkdir puppeteer-pdf-appcd puppeteer-pdf-appnpm init -ytouch generatePDF.cjsInstall Puppeteer. By default, installation also downloads a compatible Chrome for Testing browser:
Terminal window npm install puppeteer@25.11.0In
generatePDF.cjs, render a short HTML invoice to PDF:const puppeteer = require("puppeteer");async function generatePDF() {const browser = await puppeteer.launch();try {const page = await browser.newPage();await page.setContent("<h1>Invoice</h1><p>Total: $125.00</p>");await page.pdf({ path: "example.pdf", format: "A4", printBackground: true });} finally {await browser.close();}}generatePDF().catch((error) => {console.error(error);process.exitCode = 1;});Run the script:
Terminal window node generatePDF.cjsThis saves the rendered page as
example.pdf.
Common pitfalls with JavaScript PDF generator libraries
- Font embedding — Most libraries only bundle a few default fonts. Custom or Unicode fonts need to be explicitly embedded, or text renders as tofu (□□□).
- CSS fidelity — pdfmake uses its own document definitions. jsPDF has an optional HTML path, but it isn’t equivalent to Chrome’s print layout. Test your CSS and pagination with the chosen renderer.
- Memory limits in the browser — Generating large PDFs client-side can exhaust browser memory, especially with high-resolution images. Move heavy workloads to the server.
- Async page loading — Puppeteer and similar tools need explicit
waitUntilstrategies. A network-idle event alone doesn’t prove charts or lazy-loaded content are ready. Wait for an application-specific signal and required assets before printing a dynamic page. - File size — Embedded images and fonts inflate PDF size. Compress images before embedding and subset fonts to include only the glyphs you use.
Conclusion
PDFKit(opens in a new tab) suits server-side Node.js generation, while jsPDF(opens in a new tab) and pdfmake(opens in a new tab) handle client-side downloads. pdf-lib(opens in a new tab) fits workflows that modify existing PDFs, and Puppeteer(opens in a new tab) handles headless HTML-to-PDF conversion with complex layouts. For interactive browser workflows, evaluate Nutrient Web SDK and the components required for your generation and collaboration needs. To learn more about Nutrient, contact our Sales team or try our demo.
Related comparisons
FAQ
Use jsPDF for programmatic downloads, pdfmake for declarative layouts, or pdf-lib for existing PDFs and form templates. Evaluate Nutrient Web SDK when document interaction and commercial support are part of the requirements.
Puppeteer runs Chrome’s print layout. It needs a browser runtime and suitable hosting resources. PDFKit and pdfmake generate documents through their own APIs rather than rendering arbitrary HTML and CSS.
It can add content, work with form fields, and copy or rearrange pages. It isn’t a general editor for replacing arbitrary existing page text with reflow.
Web SDK’s headless option hides its UI while processing in a browser environment. Use a separate server SDK or document-processing API for a native backend integration.
Successful PDF generation alone doesn’t establish PDF/UA or PDF/A conformance. Choose a tool and workflow that support the required standard and validate the actual output.