---
title: "Best JavaScript PDF libraries 2026: A complete guide to viewers, generators, and enterprise solutions"
canonical_url: "https://www.nutrient.io/blog/javascript-pdf-libraries/"
md_url: "https://www.nutrient.io/blog/javascript-pdf-libraries.md"
last_updated: "2026-08-14T20:08:30.663Z"
description: "Compare the top JavaScript PDF libraries for 2026. In-depth analysis of PDF.js, jsPDF, Nutrient SDK, and more. Find the perfect solution for your project with our expert guide."
---

**TL;DR**

JavaScript PDF libraries fall into two main categories, but some solutions cover both:

**PDF generation** — Create new documents from scratch, from structured data, or by converting HTML.

- [PDFKit](#1-pdfkit--low-level-programmatic-control) — Low-level, full control

- [pdfmake](#2-pdfmake--declarative-syntax) — Declarative JSON syntax

- [jsPDF](#3-jspdf--client-side-simplicity) — Simple client-side PDFs

- [Puppeteer](#4-puppeteer--html-to-pdf) — HTML to PDF (server-side)

- [PDF-lib](#5-pdf-lib--creation-and-manipulation) — Generate from scratch and manipulate existing documents

**PDF viewing** — Display existing documents, fill forms, add annotations

- [PDF.js](#1-pdfjs--mozillas-open-source-standard) — Mozilla’s open source standard

- [React-PDF](#2-react-pdf--react-friendly-viewing) — React wrapper for PDF.js

**Enterprise platform** — Do both generation and viewing/editing, plus add collaboration, compliance, and scalability.

- [Nutrient SDK](#1-nutrient-sdk--enterprise-grade-document-platform) — Enterprise-grade viewer, editor, generator, and collaboration suite

- [Apryse](#2-alternative-apryse--traditional-enterprise-sdk-with-comprehensive-apis) — Enterprise SDK with strong APIs, legacy format support, and developer control

Nutrient SDK is a comprehensive document platform that covers both PDF generation and viewing/editing, making it a strong fit for end-to-end document workflows.

## Why library choice matters

The wrong PDF library leads to:

- **Performance bottlenecks** with large or complex PDFs

- **Missing functionality** requiring fragile workarounds

- **Compliance gaps** in regulated industries

- **Poor mobile experience** with client-heavy rendering

- **Hidden costs** from internal development and maintenance

## Quick comparison of popular libraries

| Library                    | Best for                 | License    | Platform           | Primary strength                                                   |
| -------------------------- | ------------------------ | ---------- | ------------------ | ------------------------------------------------------------------ |
| **[Nutrient Web SDK](https://www.nutrient.io/sdk/web/)** ★ | Enterprise PDF SDK       | Commercial | Web/cross-platform | Complete platform: generation, viewing, editing, collaboration, AI |
| **[Apryse](https://www.nutrient.io/sdk/vs/apryse/)**             | Enterprise PDF SDK       | Commercial | Web/mobile/desktop | Rich API coverage, CAD/engineering support, developer tooling      |
| **[PDF.js](https://mozilla.github.io/pdf.js/)**             | Basic viewing            | Apache 2.0 | Web browsers       | Mozilla-backed, reliable PDF rendering                             |
| **[React-PDF](https://github.com/wojtekmaj/react-pdf)**          | React-based viewing      | MIT        | React (Web)        | React-friendly PDF.js wrapper                                      |
| **[PDFKit](https://pdfkit.org/)**             | Low-level generation     | MIT        | Node.js/browser    | Programmatic PDF creation with precise control                     |
| **[pdfmake](https://www.npmjs.com/package/pdfmake)**            | Declarative generation   | MIT        | Browser/Node.js    | JSON-based PDF creation                                            |
| **[jsPDF](https://github.com/parallax/jsPDF)**              | Simple client generation | MIT        | Web browsers       | Lightweight client-side PDF creation                               |
| **[Puppeteer](https://pptr.dev/)**          | HTML to PDF              | Apache 2.0 | Node.js (server)   | Browser-based HTML/CSS-to-PDF conversion                           |
| **[PDF-lib](https://github.com/Hopding/pdf-lib)**            | PDF manipulation         | MIT        | Web/Node.js        | PDF editing and forms                                              |

## PDF generation libraries

### 1. PDFKit — Low-level programmatic control

[PDFKit](https://pdfkit.org/) is a Node.js library for programmatic PDF generation with low-level control over document structure.

**Best use cases:**

- Server-side invoice or report generation in Node.js

- Graphics-heavy PDFs (charts, paths, vector drawings, branding assets)

- Large document streaming directly to clients via HTTP responses

**Key features:**

- Full programmatic API for text, images, vector shapes, and custom fonts

- Streaming support for efficient handling of large documents

- Works primarily in Node.js, but can run in the browser via bundlers (Browserify/webpack/Rollup)

- Supports encryption, embedded fonts, and precise layout control

```javascript

// Node.js example: Generate and stream a PDF to disk.
const fs = require("fs");
const PDFDocument = require("pdfkit");

const doc = new PDFDocument({ size: "A4", margin: 50 });
doc.pipe(fs.createWriteStream("output.pdf"));

doc.fontSize(20).text("Hello PDFKit!", 100, 100);
doc.addPage().fontSize(16).text("Second page content", 50, 50);

doc.end();

```

**Note:** Tables and templates require custom helpers with PDFKit. [pdfmake](#2-pdfmake--declarative-syntax) provides these through its JSON API.

Use PDFKit for maximum control over layout logic. For declarative or HTML-based approaches, try pdfmake or Puppeteer.

### 2. pdfmake — Declarative syntax

[pdfmake](https://www.npmjs.com/package/pdfmake) extends PDFKit with a declarative JSON API that handles layout, pagination, and styling automatically.

**Best use cases:**

- Invoices, receipts, and pay slips

- Reports or catalogs generated from tabular data

- Applications needing consistent headers, footers, and multipage layouts

- Teams that prefer a configuration-driven model over manual drawing

**Key features:**

- Declarative document definitions with arrays and objects

- Built-in support for tables, lists, images, and headers/footers

- Automatic pagination and page breaks

- Embeds custom fonts with Unicode and RTL support

- Works in both browser and Node.js with the same API

```javascript

// Example: declarative invoice with pdfmake.
const docDefinition = {
  content: [
    { text: "Invoice", style: "header" },
    {
      table: {
        body: [
          ["Item", "Qty", "Price"],
          ["Widget A", "2", "$10.00"],
          ["Widget B", "1", "$15.00"],
        ],
      },
    },
  ],
  styles: {
    header: { fontSize: 22, bold: true },
  },
};

pdfMake.createPdf(docDefinition).download("invoice.pdf");

```

**Getting started:**

```bash

npm install pdfmake

```

Then import and call `pdfMake.createPdf()` with your document definition.
For browser-only projects, you can also load it via CDN.

Use pdfmake for structured layouts without manual positioning. It works for invoices, reports, and data-driven documents where JSON schemas define structure.

**Featured Content**

**Ship PDFs at enterprise scale**

Need collaboration, digital signatures, redaction, or server-side pipelines across web, server, and mobile? Explore Nutrient SDK — viewer/editor, conversion, forms, and compliance in one platform.

[Learn more](https://www.nutrient.io#1-nutrient-sdk--enterprise-grade-document-platform)

### 3. jsPDF — Client-side simplicity

[jsPDF](https://github.com/parallax/jsPDF) generates PDFs directly in the browser with no dependencies — useful for client-side exports without server roundtrips.

Unlike [PDFKit](#1-pdfkit--low-level-programmatic-control) or [pdfmake](#2-pdfmake--declarative-syntax), jsPDF focuses on quick output, not complex layouts.

**Best use cases:**

- Client-side form submissions that generate a PDF instantly

- Simple invoices, tickets, or confirmations downloaded directly by the user

- Prototypes or MVPs requiring minimal setup

- Frontend projects that need offline PDF creation with no server roundtrips

**Key features:**

- Works entirely in the browser, with optional Node.js support

- Generate text, images, and vector shapes with a simple API

- Plugin ecosystem (e.g. `autotable`) for tables, pagination, and HTML rendering

- Supports page orientation, margins, and basic styling options

- Small size (~150 KB minified) for efficient bundling

```javascript

// Basic example.
import { jsPDF } from "jspdf";

const doc = new jsPDF();
doc.text("Hello World!", 10, 10);
doc.save("document.pdf");

```

**Example with a table (using `jspdf-autotable`):**

```javascript

import { jsPDF } from "jspdf";
import "jspdf-autotable";

const doc = new jsPDF();
doc.autoTable({
  head: [["Item", "Quantity", "Price"]],
  body: [["Widget A", "2", "$10.00"]],
});
doc.save("invoice.pdf");

```

Use jsPDF for quick client-side PDFs with minimal setup — best for simple documents triggered by user actions, but limited for complex layouts, multi-language documents, or large PDFs.

### 4. Puppeteer — HTML to PDF

[Puppeteer](https://pptr.dev/) controls headless Chrome from Node.js. Use it when you need pixel-perfect PDFs from existing HTML/CSS templates.

Unlike [PDFKit](#1-pdfkit--low-level-programmatic-control) or [pdfmake](#2-pdfmake--declarative-syntax), Puppeteer reuses existing web designs for PDFs.

**Best use cases:**

- Exporting HTML reports, invoices, or dashboards without rebuilding layouts

- Rendering JavaScript-heavy pages (SPAs, charts, maps) before saving to PDF

- Pixel-perfect PDFs with CSS control (grid, flexbox, web fonts, print media queries)

- Automated workflows: batch exporting, scheduled snapshots, CI/CD pipelines

**Key features:**

- Full support for modern HTML5, CSS3, and client-side JavaScript

- Convert entire webpages or specific DOM elements into PDF

- Customizable PDF output (margins, headers/footers, background graphics, page size)

- Can run in headless mode for automation or in full Chrome for debugging

```javascript

import puppeteer from "puppeteer";

const browser = await puppeteer.launch();
const page = await browser.newPage();

await page.goto("https://example.com", { waitUntil: "networkidle0" });
await page.pdf({
  path: "example.pdf",
  format: "A4",
  printBackground: true,
});

await browser.close();

```

Use Puppeteer when PDFs must match webpages exactly — e.g. with dashboards, CSS-styled invoices, or complex layouts.

Browser instances consume significant resources, making server-side generation preferable.

For a practical example, check out our blog on [how to generate a PDF from HTML with Node.js](https://www.nutrient.io/blog/how-to-generate-pdf-from-html-with-nodejs.md).

### 5. PDF-lib — Creation and manipulation

[PDF-lib](https://github.com/Hopding/pdf-lib) handles both PDF generation and modification in the browser and Node.js environments without native dependencies.

**Best use cases:**

- Generating custom PDFs from scratch (reports, receipts, lightweight exports)

- Filling PDF forms (applications, contracts, HR onboarding)

- Adding digital signatures, watermarks, or images

- Merging or splitting multiple PDFs

- Editing or extending predesigned templates

**Key features:**

- Create new PDFs programmatically with pages, text, fonts, images, and vector graphics

- Load and modify existing PDF documents

- Fill AcroForms and programmatically set field values

- Insert pages or overlay images and shapes

- Merge and split PDFs without external binaries

- Supports both ES modules and CommonJS in modern toolchains

```typescript

import { PDFDocument } from "pdf-lib";

// Load an existing PDF and fill a form field.
const existingBytes = await fetch("/form.pdf").then((res) => res.arrayBuffer());
const pdfDoc = await PDFDocument.load(existingBytes);

const form = pdfDoc.getForm();
form.getTextField("name").setText("Alice Example");

const pdfBytes = await pdfDoc.save();
// `pdfBytes` can be downloaded in the browser or written to disk in Node.js.

```

Use PDF-lib for template workflows (government forms, invoices, contracts) and post-processing (merging, stamping). For complex PDFs from scratch, try [pdfmake](#2-pdfmake--declarative-syntax) or [Puppeteer](#4-puppeteer--html-to-pdf). PDF-lib handles both generation and editing.

- [How to build a JavaScript PDF editor with PDF-lib](https://www.nutrient.io/blog/how-to-build-a-javascript-pdf-editor/)

- [How to fill PDF forms in Node.js](https://www.nutrient.io/blog/how-to-fill-pdf-form-in-nodejs/)

- [How to capture signatures in JavaScript](https://www.nutrient.io/blog/how-to-capture-signatures-in-javascript/)

## PDF viewing libraries

Viewing existing PDFs requires different considerations than generation, such as:

- **How interactive should the viewer be?** (read-only vs. annotations vs. full editing)

- **What level of performance do you need?** (simple documents vs. 500 MB financial reports)

- **What are your compliance and budget requirements?** (free OSS vs. enterprise-grade security and support)

Three libraries dominate this space.

### 1. PDF.js — Mozilla’s open source standard

[PDF.js](https://mozilla.github.io/pdf.js/) is Mozilla’s open source PDF viewer, originally built for Firefox. With more than 53k GitHub stars, it’s the standard for basic PDF rendering.

It renders PDFs onto HTML5 `<canvas>` with a text layer for search and copy-paste.

**Key capabilities:**

- **Cross-browser compatibility** across all modern browsers

- **Canvas-based rendering** with solid fidelity for most documents

- **Selectable text layer**, enabling search and copy-paste

- **Basic annotation viewing** (read-only, no edits)

- **Native print support**

**Limitations:**

- **Read-only** — No annotation editing, form filling, or collaboration

- **Performance bottlenecks** with very large or graphics-heavy PDFs

- **Customization overhead** — Modifying the default viewer UI often requires editing source code

- **No enterprise features** like permissions, redaction, or audit logs

**Code example — Minimal viewer:**

```html

<canvas id="pdf-canvas"></canvas>

<script type="module">
  import * as pdfjsLib from "https://cdn.jsdelivr.net/npm/pdfjs-dist@6.1.200/+esm";

  // Set worker.
  pdfjsLib.GlobalWorkerOptions.workerSrc =
    "https://cdn.jsdelivr.net/npm/pdfjs-dist@6.1.200/build/pdf.worker.min.mjs";

  const url = "example.pdf"; // Put your PDF in the same folder.
  const canvas = document.getElementById("pdf-canvas");
  const ctx = canvas.getContext("2d");

  // Load PDF.
  const loadingTask = pdfjsLib.getDocument(url);
  loadingTask.promise.then(async (pdf) => {
    const page = await pdf.getPage(1);
    const viewport = page.getViewport({ scale: 1.5 });

    canvas.width = viewport.width;
    canvas.height = viewport.height;

    const renderContext = { canvasContext: ctx, viewport };
    await page.render(renderContext).promise;
  });
</script>

```

**Best for:**

- Lightweight projects needing only rendering

- Teams with budget constraints willing to invest development time

- Applications requiring custom UI or annotation layers

For a deeper dive, see:

- [Complete guide to PDF.js](https://www.nutrient.io/blog/complete-guide-to-pdfjs.md)

- [PDF.js vs. Nutrient Web SDK](https://www.nutrient.io/blog/pdfjs-vs-nutrient/)

- [Building a PDF viewer with JavaScript](https://www.nutrient.io/blog/how-to-build-a-javascript-pdf-viewer-with-pdfjs.md)

### 2. React-PDF — React-friendly viewing

[React-PDF] provides React components (`<Document>` and `<Page>`) that wrap PDF.js functionality.

**Key capabilities:**

- **React-first design** with props, hooks, and state

- **Responsive rendering** that integrates smoothly into React layouts

- **Powered by PDF.js** — Inherits its rendering engine and limitations

- **TypeScript support** with full typings out of the box

**Code example:**

```javascript

import { Document, Page } from "react-pdf";
import { useState } from "react";

function PDFViewer({ file }) {
  const [numPages, setNumPages] = useState(null);

  return (
    <Document
      file={file}
      onLoadSuccess={({ numPages }) => setNumPages(numPages)}
    >
      {Array.from({ length: numPages }, (_, i) => (
        <Page key={i} pageNumber={i + 1} />
      ))}
    </Document>
  );
}

```

**Best for:**

- React apps needing PDF rendering with minimal boilerplate

- Teams staying within the React ecosystem

- Projects requiring view-only functionality (no editing or annotations)

See more:

- [How to build a React PDF viewer with React-PDF](https://www.nutrient.io/blog/how-to-build-a-reactjs-pdf-viewer-with-react-pdf.md)

- [React PDF viewer with Nutrient SDK](https://www.nutrient.io/guides/web.md)

## Enterprise PDF platforms

Nutrient SDK represents a modern, unified approach to enterprise document workflows — built for collaboration, compliance, and AI from the ground up. By contrast, traditional options like Apryse still deliver deep PDF capabilities but rely on older architectures that require more integration effort and custom infrastructure.

### 1. Nutrient SDK — Enterprise-grade document platform

[Nutrient SDK](https://www.nutrient.io/sdk/) is a unified document platform spanning web, server, and mobile and covering viewing, editing, generation, collaboration, and compliance in one stack.

[Explore Web demo](https://www.nutrient.io/demo/)

**Why teams pick it:**

- [Built-in collaboration](https://www.nutrient.io/guides/web/instant-synchronization.md): real-time presence, comments, cursors, and a full [annotation](https://www.nutrient.io/guides/web/annotations.md) suite.

- Compliance and [security](https://www.nutrient.io/guides/web/document-security.md): roles/permissions (RBAC), audit trails, [encryption](https://www.nutrient.io/sdk/solutions/security-compliance-privacy/), and self-hosting options.

- [AI-ready workflows](https://www.nutrient.io/guides/ai-assistant.md): summarization, extraction, comparison, and smart redaction.

- End-to-end [generation](https://www.nutrient.io/sdk/solutions/generation/): HTML/Word/PDF templates, headless pipelines, export of [forms](https://www.nutrient.io/guides/web/forms.md)/annotations.

- Developer experience: consistent [rendering](https://www.nutrient.io/guides/web/viewer.md), accessible [UI](https://www.nutrient.io/guides/web/viewer/accessibility.md), JSON-first data flows, container-friendly deployment.

**Great for:**

- Governed workflows in legal, finance, healthcare, and public sector

- Apps that combine viewing + editing + eSigning + conversion

- Teams standardizing on a single platform across client and server

#### Example: Load a viewer with AI assistance

```javascript

NutrientViewer.load({
  container: "#nutrient",

  document: "source.pdf",
  licenseKey: "<your-license-key>",
  aiAssistant: {
    sessionId: "<your-session-id>",
    jwt: "<your-jwt-token>",
    backendUrl: "https://your-ai-backend.com",
  },
});

```

Replace the placeholders with your actual values:

- `<your-license-key>` — Your Nutrient SDK license key (can be omitted for trial with watermark).

- `<your-session-id>` — A unique session ID for the AI chat.

- `<your-jwt-token>` — A valid JWT generated for AI Assistant authentication.

- `https://your-ai-backend.com` — The URL where your AI Assistant backend is running.

This loads the Nutrient viewer with AI Assistant UI for summarization, smart redaction, and auto-field generation.

For full setup details, refer to [AI Assistant integration with Nutrient Web SDK](https://www.nutrient.io/guides/ai-assistant/viewer-integration/nutrient-web-sdk.md).

[Start a free trial](https://www.nutrient.io/sdk/try/), explore the [Web SDK documentation](https://www.nutrient.io/sdk/web/), or [contact Sales](https://www.nutrient.io/contact-sales?=sdk) for custom enterprise solutions.

### 2. Alternative: Apryse — Traditional enterprise SDK with comprehensive APIs

[Apryse](https://www.nutrient.io/sdk/vs/apryse/) (formerly PDFTron) is a mature enterprise PDF SDK serving organizations for more than two decades with comprehensive PDF functionality across platforms. While feature-rich, its architecture reflects legacy decisions that modern alternatives have addressed.

**Why teams pick it:**

- Comprehensive PDF primitives, forms, and signatures

- Strong engineering/CAD format support (e.g. DWG, DGN)

- Mature, cross-platform tooling and documentation

**Limitations for modern workflows:**

- **Complex integration** — XML/XFDF data model increases development complexity

- **Infrastructure overhead** — Real-time collaboration requires custom server development

- **Limited AI readiness** — No built-in generative AI capabilities

- **High TCO** — Significant infrastructure and development costs for modern features

**Best for:**

- Teams prioritizing deep PDF control and engineering formats

- Enterprises invested in Apryse and comfortable with custom infrastructure

## Nutrient vs. Apryse at a glance

| Dimension                   | Nutrient SDK                                                       | Apryse                                                                                  |
| --------------------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------- |
| **Architecture**            | Unified codebase refined since 2011; JSON-first data flows         | Legacy core (late 90s) extended via acquisitions/wrappers                               |
| **Collaboration**           | Built-in real time (presence, cursors, comments)                   | Requires custom server infrastructure to replicate similar UX                           |
| **AI readiness**            | Native AI Assistant (summarize, redact, extract, compare)          | No built-in generative AI; traditional APIs                                             |
| **Data model**              | JSON-first (friendly for pipelines/AI ops)                         | XFDF/XML-centric; heavier to adapt for AI                                               |
| **Rendering and UX**        | Pixel-perfect viewing, [responsive UI](https://www.nutrient.io/guides/web/viewer/mobile-responsive.md), accessibility      | Mature rendering; strong control via APIs                                               |
| **Forms and signing**       | AcroForms, validation, eSign, export/import                        | Rich forms/signature APIs                                                               |
| **Generation**              | HTML/Word/PDF templates; headless server pipelines                 | Extensive low-level generation/editing APIs                                             |
| **CAD/engineering formats** | General document focus                                             | Strong: DWG, DGN, and technical formats                                                 |
| **Deployment**              | SaaS, self-hosted Docker/K8s, or managed                           | Broad platform support; more DIY for containerized, multi-tenant                        |
| **TCO**                     | Lower infrastructure lift for collaboration/AI; fewer moving parts | Higher infrastructure and development effort for collaboration, pipelines, multi-tenant |
| **Best fit**                | Enterprise workflows needing collaboration, compliance, AI         | Deep PDF API control, specialized engineering formats                                   |

## Comprehensive feature comparison matrix

Choosing the right PDF or document SDK often comes down to how well it balances core functionality, advanced features, and enterprise requirements. To help you compare at a glance, we’ve compiled a detailed side-by-side matrix of Nutrient SDK, Apryse, and leading open source libraries. This overview highlights what each option delivers out of the box and where additional development effort may be required.

### Core functionality

| Feature                 | Nutrient       | Apryse      | PDF.js     | React-PDF  | jsPDF     | PDF-lib   | pdfmake    | PDFKit     | Puppeteer   |
| ----------------------- | -------------- | ----------- | ---------- | ---------- | --------- | --------- | ---------- | ---------- | ----------- |
| **Document viewing**    |                |             |            |            |           |           |            |            |             |
| High-fidelity rendering | ✅ Excellent    | ✅ Excellent | ✅ Good     | ✅ Good     | ❌ N/A     | ❌ N/A     | ❌ N/A      | ❌ N/A      | ❌ N/A       |
| Mobile responsiveness   | ✅ Full support | ✅ Full      | ✅ Basic    | ✅ React    | ✅ Basic   | ❌ N/A     | ✅ Basic    | ✅ Basic    | ❌ N/A       |
| Zoom and navigation     | ✅ Advanced     | ✅ Advanced  | ✅ Standard | ✅ Standard | ❌ N/A     | ❌ N/A     | ❌ N/A      | ❌ N/A      | ❌ N/A       |
| Search functionality    | ✅ Advanced     | ✅ Advanced  | ✅ Basic    | ✅ Basic    | ❌ No      | ❌ N/A     | ❌ No       | ❌ No       | ❌ N/A       |
| Print support           | ✅ Advanced     | ✅ Advanced  | ✅ Standard | ✅ Standard | ✅ Client  | ❌ N/A     | ✅ Client   | ✅ Basic    | ❌ N/A       |
| **Document creation**   |                |             |            |            |           |           |            |            |             |
| Create from scratch     | ✅ Advanced     | ✅ Full      | ❌ No       | ❌ No       | ✅ Basic   | ✅ Basic   | ✅ Full     | ✅ Full     | ❌ No        |
| Template support        | ✅ Advanced     | ✅ Good      | ❌ No       | ❌ No       | ✅ Good    | ✅ Good    | ✅ Full     | ✅ Limited  | ✅ HTML/CSS  |
| Dynamic content         | ✅ Full         | ✅ Full      | ❌ No       | ❌ No       | ✅ Good    | ✅ Good    | ✅ Full     | ✅ Good     | ✅ Full      |
| Complex layouts         | ✅ Yes          | ✅ Yes       | ❌ No       | ❌ No       | ❌ Limited | ❌ Limited | ✅ Advanced | ✅ Advanced | ✅ Excellent |

### Advanced features

| Feature                | Nutrient          | Apryse                               | PDF.js      | React-PDF   | jsPDF     | PDF-lib          | pdfmake   | PDFKit    | Puppeteer |
| ---------------------- | ----------------- | ------------------------------------ | ----------- | ----------- | --------- | ---------------- | --------- | --------- | --------- |
| **Annotations**        |                   |                                      |             |             |           |                  |           |           |           |
| View annotations       | ✅ All types       | ✅ All types                          | ✅ Basic     | ✅ Basic     | ❌ No      | ❌ N/A (headless) | ❌ No      | ❌ No      | ❌ No      |
| Create annotations     | ✅ Full suite      | ✅ Full suite                         | ❌ No        | ❌ No        | ❌ No      | ✅ Basic (API)    | ❌ No      | ❌ No      | ❌ No      |
| Collaborative editing  | ✅ Real time       | ✅ Available (requires custom server) | ❌ No        | ❌ No        | ❌ No      | ❌ No             | ❌ No      | ❌ No      | ❌ No      |
| **Forms**              |                   |                                      |             |             |           |                  |           |           |           |
| Display forms          | ✅ Advanced        | ✅ Advanced                           | ✅ Read-only | ✅ Read-only | ❌ Limited | ❌ N/A (no UI)    | ✅ Limited | ✅ Limited | ❌ No      |
| Fill forms             | ✅ Interactive     | ✅ Interactive                        | ❌ No        | ❌ No        | ❌ No      | ✅ Programmatic   | ✅ Limited | ✅ Limited | ❌ No      |
| Create forms           | ✅ Visual editor   | ✅ Code-based                         | ❌ No        | ❌ No        | ❌ No²     | ✅ Code           | ✅ JSON    | ✅ Code    | ❌ No      |
| Form validation        | ✅ Advanced        | ✅ Advanced                           | ❌ No        | ❌ No        | ❌ No      | ✅ Basic          | ✅ Basic   | ✅ Basic   | ❌ No      |
| **Digital signatures** |                   |                                      |             |             |           |                  |           |           |           |
| View signatures        | ✅ All types       | ✅ All types                          | ✅ Basic     | ✅ Basic     | ❌ No      | ❌ N/A (no UI)    | ❌ No      | ❌ No      | ❌ No      |
| Create signatures      | ✅ eSign + digital | ✅ Digital                            | ❌ No        | ❌ No        | ❌ No      | ✅ Basic (stamp)  | ❌ No      | ❌ No      | ❌ No      |
| PKI support            | ✅ Full            | ✅ Full                               | ❌ No        | ❌ No        | ❌ No      | ❌ Limited        | ❌ No      | ❌ No      | ❌ No      |

### Enterprise features

| Feature            | Nutrient    | Apryse       | PDF.js                | React-PDF         | jsPDF     | PDF-lib                                             | pdfmake   | PDFKit    | Puppeteer |
| ------------------ | ----------- | ------------ | --------------------- | ----------------- | --------- | --------------------------------------------------- | --------- | --------- | --------- |
| **Security**       |             |              |                       |                   |           |                                                     |           |           |           |
| Encryption support | ✅ AES 256   | ✅ AES 256    | ✅ Open encrypted PDFs | ✅ Inherits PDF.js | ❌ Limited | ❌ No built-in encryption for writing protected PDFs | ✅ Basic   | ✅ Basic   | ❌ No      |
| Access controls    | ✅ Granular  | ✅ Role-based | ❌ Limited             | ❌ Limited         | ❌ No      | ❌ Limited                                           | ❌ No      | ❌ No      | ❌ No      |
| **Compliance**     |             |              |                       |                   |           |                                                     |           |           |           |
| PDF/A support      | ✅ Supported | ✅ Supported  | ❌ No                  | ❌ No              | ❌ No      | ❌ Limited                                           | ❌ Limited | ❌ Limited | ❌ No      |

_Notes:_

- “Encryption support” here means applying PDF encryption in output and not just opening PDFs with passwords. PDF.js and React-PDF _open_ encrypted PDFs; they don’t encrypt outputs.

- PDF-lib currently doesn’t ship password-protection/encryption APIs.

- Puppeteer generates PDFs from HTML; it doesn’t apply PDF/A or signatures.

## Pricing analysis and total cost of ownership

Total cost includes licensing, support, development time, and infrastructure scaling.

### Open source hidden costs

PDF.js, React-PDF, jsPDF, PDF-lib, pdfmake, and PDFKit are free. Puppeteer is free but needs Chromium and server infrastructure.

Free libraries carry operational costs:

- **Development time** — Adding annotations, collaboration, compliance, or scaling features requires hundreds of engineering hours

- **Support and maintenance** — Community projects lack SLAs; fixes and patches follow community timelines

- **Compliance and security** — GDPR, HIPAA, PDF/A, and audit logging must be built from scratch

- **Scalability and infrastructure** — Scaling Puppeteer or PDF.js for thousands of users requires load balancers, monitoring, and clustering

### Commercial solutions

**Nutrient Web SDK**

- **Development license** — Keys available for prototyping/QA/staging

- **Production** — Pricing based on components/products and total users. Costs scale with application and user base. [See details](https://www.nutrient.io/sdk/pricing/).

- **Enterprise packages** — Tailored plans with SLA support, compliance options, and flexible deployment (cloud, on-premises, or dedicated hosting).

- **Transparent model** — User- and component-based pricing without per-document or per-operation fees. (Note: Some low-code/automation products may include operation limits.)

- **Includes** — SLA‑backed support, compliance guarantees, frequent updates, and enterprise deployment options.

- **ROI** — Minimal engineering burden with built-in audit/logging, AI processing, collaboration, and compliance.

**Apryse PDF SDK**

- **Pricing model** — Commercial license; pricing custom‑quoted based on API usage, platforms supported, and deployment size.

- **Strengths** — Broad platform support (web, mobile, desktop), deep API coverage, CAD/engineering file handling, rich form and signature support.

- **Considerations**
  - Developer workload may increase: Real-time collaboration needs a custom backend.
  - XML/XFDF-based annotation workflow can be more verbose and less AI-friendly.
  - No built-in generative AI layer as of publication.

- **ROI tradeoff** — Extensive capabilities, with additional integration and infrastructure work for modern features.

## ROI use case summary

Different organizations have very different cost, risk, and compliance profiles depending on their scale and architecture. The following scenarios illustrate how Nutrient compares with Apryse and open source stacks in common enterprise situations.

### 1. Enterprise document workflows (1,000+ users)

| Option               | Cost profile              | Risk profile | Compliance readiness*                 |
| -------------------- | ------------------------- | ------------ | ------------------------------------- |
| **Nutrient Web SDK** | Predictable subscription  | Low          | Supported (depends on configuration)  |
| **Apryse SDK**       | License + custom servers  | Medium       | Supported (more customer-implemented) |
| **OSS stack**        | Engineering + infra spend | High         | Custom-built                          |

\*Compliance depends on your deployment, policies, and data handling.

### 2. High-volume server processing (100K+ documents/month)

| Option                                     | Cost profile                  | Performance | Maintenance load                                          |
| ------------------------------------------ | ----------------------------- | ----------- | --------------------------------------------------------- |
| **[Nutrient Document Engine](https://www.nutrient.io/sdk/document-engine/getting-started.md)** | Subscription                  | High        | Low                                                       |
| **Apryse Server SDK**                      | Commercial license            | High        | Medium (requires custom infrastructure and orchestration) |
| **OSS stack**                              | Dev time + infrastructure ops | Variable    | High                                                      |
| **Puppeteer-based**                        | Infrastructure + scaling ops  | High        | Medium–High                                               |

## Migrating from legacy PDF solutions

When applications outgrow PDF.js or custom viewers, migration paths vary based on requirements for viewing, collaboration, or compliance.

### From PDF.js → Enterprise SDK

Many teams start with PDF.js for basic, low-cost PDF viewing. As requirements grow, an enterprise SDK becomes the logical next step. Migrating doesn’t have to be disruptive if you plan it in stages.

#### Typical migration path

1. **Assessment** — Identify how PDF.js (or similar tools) are currently used (viewing, search, basic annotation).

2. **Feature gap analysis** — List features required but missing (e.g. collaboration, redaction, signatures).

3. **Pilot rollout** — Start with a small group of users to validate functionality.

4. **Gradual migration** — Use feature flags to toggle between viewers until the new system is stable.

#### Annotation and data migration

Migrating from Adobe, Foxit, or custom formats requires annotation remapping. Nutrient’s unified annotation model maintains consistency across platforms, reduces cross-platform differences, and can help avoid format lock-in.

#### Staged migration strategy

- **Phase 1** — Run both systems side by side and collect performance baselines.

- **Phase 2** — Pilot with a small group, gather feedback, and optimize workflows.

- **Phase 3** — Roll out broadly with rollback options available.

Feature flags let you toggle between old and new implementations without disrupting users.

### From Apryse → Nutrient SDK

Enterprises [switching from Apryse (formerly PDFTron) to Nutrient](https://www.nutrient.io/sdk/vs/apryse/) face different migration drivers:

- **Simplifying architecture** → Convert XFDF/XML annotation stores to Nutrient’s JSON model via conversion scripts/tools.

- **Collaboration** → Apryse typically requires a custom server for real-time features; Nutrient provides a built-in real-time layer.

- **AI workflows** → Nutrient includes summarization, extraction, comparison, and smart redaction; Apryse doesn’t ship a generative AI layer as of publication.

- **Deployment flexibility** → Nutrient is cloud-ready with Docker and managed hosting options; Apryse often requires more custom infrastructure setup.

**Typical Apryse → Nutrient migration path**

1. **Audit current usage** — Which Apryse APIs are in play (viewing, forms, CAD files, signatures)?

2. **Feature mapping** — Match Apryse functions to Nutrient equivalents, noting where Nutrient’s AI/collaboration can replace custom code.

3. **Data migration** — Convert XFDF/XML annotation stores into Nutrient’s JSON annotation model.

4. **Pilot rollout** — Test Nutrient SDK with a subset of workflows.

5. **Cutover** — Phase out Apryse SDK once feature parity and stability are validated.

Timelines vary by scope, data volume, and internal review processes.

**What changes most**

- Annotation and collaboration layers (XML → JSON).

- Integration complexity (wrappers vs. unified APIs).

- Optional removal of custom servers if you adopt Nutrient’s built-in collaboration and AI services.

## Key decision factors

**Quick tip:** Start with PDF.js for basic viewing. Then upgrade to enterprise solutions as requirements grow.

1. **Document volume and size** — If sizes and traffic grow, consider commercial options for support and scale.

2. **Performance thresholds** — Open source viewers handle many use cases; enterprise SDKs can be architected for higher concurrency.

3. **Developer hours available** — Open source often requires weeks to months to make it production-ready for advanced features.

## FAQ

#### What’s the difference between PDF generation and PDF viewing libraries?

PDF generation libraries (PDFKit, pdfmake, jsPDF, PDF-lib) create new PDF documents from scratch or convert content (HTML, data) into PDFs. Use them to produce documents programmatically.
PDF viewing libraries (PDF.js, React-PDF) display existing PDF files in web browsers. They handle rendering, navigation, and basic interactions with preexisting PDFs.
Hybrid solutions — Nutrient SDK covers generation, viewing, and editing in one platform.

#### Can I use PDF.js for commercial projects?

Yes. PDF.js uses the Apache 2.0 license for commercial use, modification, and distribution. Include the license notice and copyright statements.

#### What makes Nutrient different from open source alternatives?

Nutrient SDK is a comprehensive document platform that combines PDF generation, viewing, editing, and collaboration in a single solution. Unlike open source libraries that typically focus on one area, Nutrient provides:

- Enterprise-grade security and compliance features

- Real-time collaboration and annotation capabilities

- Cross-platform consistency (web, mobile, server)

- Professional support and SLA guarantees

- Built-in AI features for document processing

It’s built for businesses needing production-ready document workflows without custom open source development.

#### Which library should I choose for React applications?

- For viewing only: React-PDF provides React components that wrap PDF.js functionality.

- For basic generation: jsPDF works well for simple client-side PDFs.

- For enterprise features: Nutrient SDK offers official React support with advanced viewing, editing, and collaboration features.

- For manipulation: PDF-lib integrates easily with React for filling forms and editing existing PDFs.

#### How do I handle large PDF files (100 MB+)?

- For viewing: Nutrient SDK and PDF.js both support streaming and progressive loading. PDF.js may struggle with very large files due to memory constraints.

- For generation: Use streaming approaches with PDFKit or pdfmake to avoid memory issues. Puppeteer can handle large documents but requires sufficient server memory.

- For processing: Server-side solutions like Nutrient Document Engine are optimized for high-volume, large document processing.

#### Can these libraries work offline?

- Client-side libraries (jsPDF, PDF-lib, PDF.js) work offline once loaded in the browser.

- Server-dependent libraries (Puppeteer) require server connectivity.

- Nutrient SDK supports offline viewing and editing with syncing capabilities when connectivity returns.

#### What about mobile compatibility?

Most libraries support mobile browsers, but with varying user experiences:

- PDF.js and React-PDF — Basic mobile support with touch scrolling

- jsPDF — Works on mobile for generation

- Nutrient SDK — Optimized mobile experience with touch gestures, responsive UI

- Puppeteer — Server-side only, mobile-irrelevant

#### How do I add annotations or form filling capabilities?

- Open source options — PDF.js only displays annotations (read-only). - You’d need to build editing capabilities from scratch.

- PDF-lib — Supports programmatic form filling and basic annotation creation.

- Nutrient SDK — Full annotation suite with collaborative editing, form creation, and real-time updates.

#### Which solution scales best for enterprise use?

- For high-volume document processing: Nutrient Document Engine or carefully architected Puppeteer clusters.

- For user-facing applications: Nutrient SDK provides enterprise scalability with built-in load balancing, caching, and CDN support.

- For cost-conscious scaling: PDF.js with custom infrastructure, though total cost of ownership often favors commercial solutions when factoring in development and maintenance time.

#### Can I migrate from one library to another later?

- From basic to advanced: Moving from PDF.js to Nutrient SDK is straightforward, as both handle viewing, with Nutrient providing migration guides.

- Between generation libraries: Different APIs require code changes, but document output is standardized PDF format.

- Data migration: Annotations and form data may need conversion when switching platforms. Nutrient provides migration tools for common formats.

## Conclusion

Your use case determines the right library:

- **High concurrency or AI-assisted workflows** — [Nutrient SDK](https://www.nutrient.io/sdk/) offers built-in real-time collaboration and AI features (summarization, extraction, comparison, smart redaction) without building a custom collaboration backend.

- **MVP or proof of concept** — [PDF.js](https://mozilla.github.io/pdf.js/) for viewing, jsPDF for simple generation — both free with community support

- **React applications** — [React-PDF](https://github.com/wojtekmaj/react-pdf) wraps PDF.js; upgrade to Nutrient when you need editing capabilities

- **Template-based workflows** — [PDF-lib](https://github.com/Hopding/pdf-lib) fills existing forms; Nutrient handles complex field validation and digital signatures

- **Server-side HTML conversion** — [Puppeteer](https://pptr.dev/) for <1,000 documents/day; [Nutrient Document Engine](https://www.nutrient.io/sdk/document-engine/getting-started.md) for production scale

- **Hosted PDF generation API** — No server to manage? See our [comparison of PDF generator APIs](https://www.nutrient.io/blog/the-six-best-pdf-generator-apis/) for cloud-based options

Most teams start with PDF.js and hit limitations as usage grows or when compliance enters the picture, and then evaluate commercial options.

**Your next move:**

1. **Test with your actual PDFs** — Download your largest, most complex document. Does the library handle it?

2. **Measure rendering time** — Load 10 PDFs simultaneously. Track memory usage and response times.

3. **Check feature gaps** — List your must-have features. Count how many require custom development.

4. **Calculate real costs** — Developer time (200 hours × $150) often exceeds commercial licensing ($30K vs. $50K/year).

5. **Run a two-week pilot** — Pick your top two options. Build the same feature with both.

**Need help choosing?** [Contact our team](https://www.nutrient.io/contact-sales?=sdk) for assistance with your specific requirements.
---

## Related pages

- [The business case for accessibility: Five ways it drives enterprise value](/blog/5-ways-accessibility-drives-enterprise-value.md)
- [Accessibility Untangled Why It Matters Guide](/blog/accessibility-untangled-why-it-matters-guide.md)
- [Advanced Techniques For React Native Ui Components](/blog/advanced-techniques-for-react-native-ui-components.md)
- [`vector_store` holds your indexed documents (see the multimodal RAG post](/blog/agentic-rag.md)
- [Ai Document Automation Extraction To Action](/blog/ai-document-automation-extraction-to-action.md)
- [Ai Legal Assistant Document Authoring](/blog/ai-legal-assistant-document-authoring.md)
- [Angular File Viewer Pdf Image Office Files](/blog/angular-file-viewer-pdf-image-office-files.md)
- [Auto Tagging And Document Accessibility In Dotnet Sdk](/blog/auto-tagging-and-document-accessibility-in-dotnet-sdk.md)
- [Best Document Ai Platforms](/blog/best-document-ai-platforms.md)
- [Best Document Viewers](/blog/best-document-viewers.md)
- [Build Vs Buy Document Extraction](/blog/build-vs-buy-document-extraction.md)
- [The CEO’s AI playbook: Why decision architecture beats model selection](/blog/ceo-ai-playbook-decision-architecture.md)
- [1. Extract and chunk the PDF.](/blog/chat-with-pdf.md)
- [Complete Guide To Pdfjs](/blog/complete-guide-to-pdfjs.md)
- [Construction Document Data Extraction](/blog/construction-document-data-extraction.md)
- [Convert One Drive Files To Pdf In Sharepoint](/blog/convert-one-drive-files-to-pdf-in-sharepoint.md)
- [Create And Edit Pdfs In Flutter](/blog/create-and-edit-pdfs-in-flutter.md)
- [Create Pdfs With React](/blog/create-pdfs-with-react.md)
- [Creating A Document Scanner With Ocr In Python](/blog/creating-a-document-scanner-with-ocr-in-python.md)
- [Creating And Filling Pdf Forms Programmatically In Javascript](/blog/creating-and-filling-pdf-forms-programmatically-in-javascript.md)
- [The CTO’s AI playbook: Why accountability architecture beats orchestration](/blog/cto-ai-playbook-accountability-architecture.md)
- [Digital Signatures](/blog/digital-signatures.md)
- [Digital Workflow Automation](/blog/digital-workflow-automation.md)
- [Document Ai Vs Ocr](/blog/document-ai-vs-ocr.md)
- [Document Extraction Confidence Scores](/blog/document-extraction-confidence-scores.md)
- [Document Viewer](/blog/document-viewer.md)
- [Document Watermarking](/blog/document-watermarking.md)
- [Emerging threats: Your logging system may be an agentic threat vector](/blog/emerging-threats-your-logging-system.md)
- [Extract Patient Data On Premises](/blog/extract-patient-data-on-premises.md)
- [app.py](/blog/extract-text-from-pdf-using-python.md)
- [Fillable Pdf](/blog/fillable-pdf.md)
- [How To Add Digital Signature To Pdf Using React](/blog/how-to-add-digital-signature-to-pdf-using-react.md)
- [How To Build A Dotnet Maui Pdf Viewer](/blog/how-to-build-a-dotnet-maui-pdf-viewer.md)
- [How To Build A Flutter Pdf Viewer](/blog/how-to-build-a-flutter-pdf-viewer.md)
- [or](/blog/how-to-build-a-javascript-pdf-viewer-with-pdfjs.md)
- [How To Build A Javascript Pdf Viewer](/blog/how-to-build-a-javascript-pdf-viewer.md)
- [or](/blog/how-to-build-a-nextjs-pdf-viewer.md)
- [How To Build A Powerpoint Viewer Using Javascript](/blog/how-to-build-a-powerpoint-viewer-using-javascript.md)
- [Using Yarn](/blog/how-to-build-a-react-excel-viewer.md)
- [How To Build A React Native Pdf Viewer](/blog/how-to-build-a-react-native-pdf-viewer.md)
- [How To Build A React Powerpoint Viewer](/blog/how-to-build-a-react-powerpoint-viewer.md)
- [How To Build A Reactjs File Viewer](/blog/how-to-build-a-reactjs-file-viewer.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer-with-react-pdf.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer.md)
- [How To Build A Reactjs Viewer With Pdfjs](/blog/how-to-build-a-reactjs-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer With Pdfjs](/blog/how-to-build-a-vuejs-pdf-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer](/blog/how-to-build-a-vuejs-pdf-viewer.md)
- [How To Build An Android Pdf Viewer](/blog/how-to-build-an-android-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Ng2 Pdf Viewer](/blog/how-to-build-an-angular-pdf-viewer-with-ng2-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Pdfjs](/blog/how-to-build-an-angular-pdf-viewer-with-pdfjs.md)
- [How To Convert Docx To Pdf Using Javascript](/blog/how-to-convert-docx-to-pdf-using-javascript.md)
- [How To Convert Docx To Pdf Using Python](/blog/how-to-convert-docx-to-pdf-using-python.md)
- [How To Convert Html To Pdf Using Html2pdf](/blog/how-to-convert-html-to-pdf-using-html2pdf.md)
- [or](/blog/how-to-convert-html-to-pdf-using-react.md)
- [How To Convert Html To Pdf Using Wkhtmltopdf And Csharp](/blog/how-to-convert-html-to-pdf-using-wkhtmltopdf-and-csharp.md)
- [or](/blog/how-to-convert-html-to-pdf-using-wkhtmltopdf-and-python.md)
- [How To Convert Word To Pdf In Nodejs](/blog/how-to-convert-word-to-pdf-in-nodejs.md)
- [or](/blog/how-to-create-a-react-js-signature-pad.md)
- [How To Create Pdfs With React To Pdf](/blog/how-to-create-pdfs-with-react-to-pdf.md)
- [How To Edit Pdfs Using Ios Pdf Library](/blog/how-to-edit-pdfs-using-ios-pdf-library.md)
- [How To Embed A Pdf Viewer In Your Website](/blog/how-to-embed-a-pdf-viewer-in-your-website.md)
- [How To Extract Tables From Pdf And Images](/blog/how-to-extract-tables-from-pdf-and-images.md)
- [How To Generate Pdf From Html With Nodejs](/blog/how-to-generate-pdf-from-html-with-nodejs.md)
- [base_url tells WeasyPrint where to resolve relative asset paths](/blog/how-to-generate-pdf-reports-from-html-in-python.md)
- [How To Merge Pdfs Using Javascript](/blog/how-to-merge-pdfs-using-javascript.md)
- [How To Ocr Pdfs In Linux](/blog/how-to-ocr-pdfs-in-linux.md)
- [How To Print Pdf In Csharp](/blog/how-to-print-pdf-in-csharp.md)
- [Open an image.](/blog/how-to-use-tesseract-ocr-in-python.md)
- [From an HTML string.](/blog/html-in-pdf-format.md)
- [Javascript Pdf Editors](/blog/javascript-pdf-editors.md)
- [Linearized Pdf](/blog/linearized-pdf.md)
- [or](/blog/merge-pdfs.md)
- [Swift Package Manager](/blog/mobile-pdf-sdk.md)
- [`elements` come from your document parser — each has a type and content.](/blog/multimodal-rag.md)
- [Nutrient Vs Conga Composer](/blog/nutrient-vs-conga-composer.md)
- [Online Document Viewer](/blog/online-document-viewer.md)
- [Open Pdf In Your Web App](/blog/open-pdf-in-your-web-app.md)
- [Building WCAG 2.2, Section 508, and PDF/UA-compliant PDFs with an SDK](/blog/pdf-accessibility.md)
- [Pdf Data Extraction Developer Guide](/blog/pdf-data-extraction-developer-guide.md)
- [Pdf Extraction Benchmark Opendataloader Bench](/blog/pdf-extraction-benchmark-opendataloader-bench.md)
- [Pdf Extraction Document Case Studies](/blog/pdf-extraction-document-case-studies.md)
- [Pdf Page Labels](/blog/pdf-page-labels.md)
- [Pdf Sdk Compliance Security Checklist](/blog/pdf-sdk-compliance-security-checklist.md)
- [Pdf Sdk Performance Benchmark](/blog/pdf-sdk-performance-benchmark.md)
- [Pdf Ua Compliance Guide](/blog/pdf-ua-compliance-guide.md)
- [Pdfjs Accessibility Structtree Printing](/blog/pdfjs-accessibility-structtree-printing.md)
- [Pdfjs Advanced Loading Streaming Workers](/blog/pdfjs-advanced-loading-streaming-workers.md)
- [Pdfjs Annotation Editor Layer](/blog/pdfjs-annotation-editor-layer.md)
- [Pdfjs Area Annotations Canvas Capture](/blog/pdfjs-area-annotations-canvas-capture.md)
- [Pdfjs Coordinate Systems Pdf To Screen](/blog/pdfjs-coordinate-systems-pdf-to-screen.md)
- [Pdfjs Document Outline Bookmarks Metadata](/blog/pdfjs-document-outline-bookmarks-metadata.md)
- [Pdfjs Eventbus Guide](/blog/pdfjs-eventbus-guide.md)
- [macOS](/blog/pdfjs-file-format-conversion-to-pdf.md)
- [macOS](/blog/pdfjs-generating-pdf-thumbnails-pdf2pic.md)
- [Pdfjs Limitations Commercial Upgrade](/blog/pdfjs-limitations-commercial-upgrade.md)
- [Pdfjs Native Annotation Layer Forms](/blog/pdfjs-native-annotation-layer-forms.md)
- [Pdfjs Navigation Zoom Rotation](/blog/pdfjs-navigation-zoom-rotation.md)
- [Pdfjs Pdf Page Manipulation Pdf Lib](/blog/pdfjs-pdf-page-manipulation-pdf-lib.md)
- [Pdfjs React Viewer Setup](/blog/pdfjs-react-viewer-setup.md)
- [Pdfjs Rendering Overlays React Portals](/blog/pdfjs-rendering-overlays-react-portals.md)
- [Pdfjs Server Side Text Extraction](/blog/pdfjs-server-side-text-extraction.md)
- [Pdfjs Sticky Note Annotations](/blog/pdfjs-sticky-note-annotations.md)
- [Pdfjs Text Highlight Annotations](/blog/pdfjs-text-highlight-annotations.md)
- [Pdfjs Text Search Pdffindcontroller](/blog/pdfjs-text-search-pdffindcontroller.md)
- [Pdfjs Thumbnail Sidebar](/blog/pdfjs-thumbnail-sidebar.md)
- [Process Flows](/blog/process-flows.md)
- [React Native Pdf Annotation](/blog/react-native-pdf-annotation.md)
- [Using Yarn](/blog/react-pdf-editor.md)
- [or](/blog/sample-blog-updated.md)
- [Sdk Product Updates Q2 2026](/blog/sdk-product-updates-q2-2026.md)
- [Add DWS MCP Server to your Claude Code project.](/blog/teaching-llms-to-read-pdfs.md)
- [Open an image file.](/blog/tesseract-python-guide.md)
- [Define the HTML part of the document.](/blog/top-10-ways-to-generate-pdfs-in-python.md)
- [Top 5 Javascript Pdf Viewers](/blog/top-5-javascript-pdf-viewers.md)
- [or](/blog/top-js-pdf-libraries.md)
- [Convert an HTML file to PDF.](/blog/top-ten-ways-to-convert-html-to-pdf.md)
- [Vector Pdf](/blog/vector-pdf.md)
- [Wcag2 Accessibility Requirements Documents](/blog/wcag2-accessibility-requirements-documents.md)
- [Web Sdk Is Now Headless](/blog/web-sdk-is-now-headless.md)
- [What Are Annotations](/blog/what-are-annotations.md)
- [What Is A Vpat](/blog/what-is-a-vpat.md)
- [What Is Document Processing](/blog/what-is-document-processing.md)
- [What Is Intelligent Document Processing](/blog/what-is-intelligent-document-processing.md)
- [What Is Pdf Ua](/blog/what-is-pdf-ua.md)
- [Why Pdfium Is A Trusted Platform For Pdf Rendering](/blog/why-pdfium-is-a-trusted-platform-for-pdf-rendering.md)
- [Why Your Ai Agent Hallucinates Pdf Table Data](/blog/why-your-ai-agent-hallucinates-pdf-table-data.md)

