This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /blog/top-js-pdf-libraries.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. Top JavaScript PDF generator libraries for 2026

Table of contents

    Choose a JavaScript PDF generator by its input and runtime: structured data, HTML, or an existing PDF; browser or Node.js. Compare six options with examples.
    Top JavaScript PDF generator libraries for 2026
    Generate PDFs with one API call

    Templates, merging, and watermarking through Nutrient DWS — start with 50 free credits.

    TL;DR

    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.

    ToolTypical input and useRuntimeLicense
    PDFKitProgrammatic text, graphics, reports, and invoicesNode.js; browser builds availableMIT
    jsPDFProgrammatic browser documents; optional HTML conversionBrowser and Node.jsMIT
    pdf-libExisting PDFs, form templates, merging, and new pagesBrowser and Node.jsMIT
    pdfmakeDeclarative text, tables, styles, and page layoutBrowser and Node.jsMIT
    PuppeteerHTML and CSS rendered by ChromeNode.js controlling a browserApache 2.0
    Nutrient Web SDKInteractive document operations, PDF templates, and image-to-PDF exportBrowser; separate Nutrient products for backend processingCommercial

    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

    JavaScript PDF Viewer Nutrient Web SDK Standalone

    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 ArrayBuffer or 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:

    Terminal window
    npm init -y
    npm install @nutrient-sdk/viewer@1.21.0
    mkdir -p assets
    cp 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.zip
    unzip -q assets.zip -d assets

    Preserve 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

    1. 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.
    2. 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>
    1. In your main JavaScript file (e.g. index.js), load the viewer using the global window.NutrientViewer API:

      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:

    Terminal window
    npx serve . -l 3000

    Navigate to http://localhost:3000 to view the website.

    0:00
    0:00

    Related reading:

    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

    1. Initialize a new project and create an entry file (e.g. app.cjs):

      Terminal window
      mkdir my-pdfkit-app
      cd my-pdfkit-app
      npm init -y
      touch app.cjs
    2. Install PDFKit via npm:

      Terminal window
      npm install pdfkit@0.20.2
    3. Create 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;
      });
    4. Run the script using Node.js to generate your PDF:

      Terminal window
      node app.cjs

      Check your directory for the output.pdf file.

    Related reading:

    3. jsPDF: Browser-based JavaScript PDF generator

    jspdf logo

    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. html2canvas integration)
    • 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

    1. Install jsPDF via npm:

      Terminal window
      npm install jspdf@4.2.1
    2. Add a basic HTML file to use jsPDF in 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:

    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 fontkit integration

    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

    1. Install the library via npm:

      Terminal window
      npm install pdf-lib@1.17.1
    2. In 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;
      });
    3. Run your script to generate the PDF:

      Terminal window
      node app.cjs

    Related reading:

    5. pdfmake: Declarative JavaScript PDF generator

    pdfmake logo

    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

    1. Install pdfmake via npm:

      Terminal window
      npm install pdfmake@0.3.11
    2. Use pdfmake in 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>
    3. Serve this project with npx serve . -l 3000, open http://localhost:3000, and click Generate PDF to download a PDF.

    Related reading:

    6. Puppeteer: Headless Chrome JavaScript PDF generator

    puppeteer logo

    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

    1. Create a new directory and initialize your Node.js project:

      Terminal window
      mkdir puppeteer-pdf-app
      cd puppeteer-pdf-app
      npm init -y
      touch generatePDF.cjs
    2. Install Puppeteer. By default, installation also downloads a compatible Chrome for Testing browser:

      Terminal window
      npm install puppeteer@25.11.0
    3. In 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;
      });
    4. Run the script:

      Terminal window
      node generatePDF.cjs

      This 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 waitUntil strategies. 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

    Which JavaScript PDF library should I use in the browser?

    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.

    Which library converts HTML and CSS to PDF in Node.js?

    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.

    Can pdf-lib edit existing PDF text?

    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.

    Does headless Web SDK run directly in Node.js?

    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.

    Do these examples produce accessible or archival PDFs?

    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.

    Hulya Masharipov

    Hulya Masharipov

    Technical Writer

    Hulya is a frontend web developer and technical writer who enjoys creating responsive, scalable, and maintainable web experiences. She’s passionate about open source, web accessibility, cybersecurity privacy, and blockchain.

    Explore related topics

    50 free credits Start generating PDFs