Skip to content

Repository files navigation


modern-pdf-lib

The PDF engine for modern JavaScript

Create, parse, fill, merge, sign, and manipulate PDF documents
in Node, Deno, Bun, Cloudflare Workers, and every browser.


npm version bundle size tests TypeScript License: MIT


Get Started · Features · API · Why This?




Quick Start

npm install modern-pdf-lib
import { createPdf, PageSizes, StandardFonts, rgb } from 'modern-pdf-lib';

const doc = createPdf();
const page = doc.addPage(PageSizes.A4);
const font = await doc.embedFont(StandardFonts.Helvetica);

page.drawText('Hello from modern-pdf-lib', {
  x: 50,
  y: 750,
  size: 28,
  font,
  color: rgb(0.13, 0.13, 0.13),
});

const bytes = await doc.save();          // Uint8Array
const stream = doc.saveAsStream();       // ReadableStream
const blob = await doc.saveAsBlob();     // Blob (browsers)

CDN (no install)

Use directly in the browser via CDN — no bundler required:

<script type="module">
  import { createPdf, PageSizes, StandardFonts, rgb } from 'https://cdn.jsdelivr.net/npm/modern-pdf-lib/dist/browser.mjs';

  const doc = createPdf();
  const page = doc.addPage(PageSizes.A4);
  const font = await doc.embedFont(StandardFonts.Helvetica);
  page.drawText('Hello from CDN!', { x: 50, y: 750, size: 24, font, color: rgb(0, 0, 0) });
  const bytes = await doc.save();
  console.log('PDF size:', bytes.length, 'bytes');
</script>

Also available via:

  • unpkg: https://unpkg.com/modern-pdf-lib/dist/browser.mjs
  • esm.sh: https://esm.sh/modern-pdf-lib

Script Tag (no modules)

For environments without ES module support, use the IIFE bundle which exposes a window.ModernPdf global:

<script src="https://cdn.jsdelivr.net/npm/modern-pdf-lib/dist/modern-pdf-lib.iife.js"></script>
<script>
  const { createPdf, PageSizes, StandardFonts, rgb } = ModernPdf;

  const doc = createPdf();
  const page = doc.addPage(PageSizes.A4);
  doc.embedFont(StandardFonts.Helvetica).then(function (font) {
    page.drawText('Hello from script tag!', { x: 50, y: 750, size: 24, font, color: rgb(0, 0, 0) });
    return doc.save();
  }).then(function (bytes) {
    console.log('PDF size:', bytes.length, 'bytes');
  });
</script>

Features

Create & Draw

  • Pages, text, images, shapes, SVG paths
  • TrueType & OpenType font embedding
  • Automatic font subsetting
  • JPEG / PNG image embedding
  • Image optimization (JPEG recompression, dedup, grayscale)
  • RGB, CMYK, grayscale, spot, DeviceN colors
  • Linear & radial gradients, tiling patterns
  • Text layout (multiline, combed, auto-size)
  • Header/footer engine with templates
  • Advanced text layout (Knuth-Plass, hyphenation)

Parse, Render & Modify

  • Load existing PDFs (encrypted too)
  • Extract text with positions
  • Render pages to PNG / Canvas (any DPI)
  • Thumbnails & visual diff (pixel + SSIM)
  • Extract embedded images & fonts
  • OCR overlay & true content-removal redaction
  • Fill & flatten AcroForm fields
  • Merge, split, copy pages; incremental saves

Secure & Compliant

  • AES-256 / RC4 encryption & decryption
  • Digital signatures (PKCS#7, visible/invisible, timestamps)
  • CRL/OCSP revocation checking & certificate chain validation
  • Incremental save with signature preservation
  • Multi-signature chains, MDP certification, LTV archival
  • Counter-signatures & field locking
  • PDF/A-1b through PDF/A-3u validation, PDF/A-4/4e/4f
  • PDF/X-6, PDF/VT, Factur-X / ZUGFeRD e-invoicing
  • Tagged PDF / PDF/UA-1 & PDF/UA-2 accessibility
  • Structure tree & marked content
  • Redaction with content removal & overlay
  • PDF/UA validation & auto-enforcement

Advanced

  • QR codes & barcodes (9 formats)
  • Table layout engine with pagination
  • JSX / VDOM component renderer (renderJsxToPdf)
  • JSON Schema → AcroForm generation
  • Server adapters (pdfResponse for Workers/Deno/Bun/Node)
  • JPEG2000 (JPXDecode) image support
  • WebP image embedding (lossy, lossless, alpha)
  • TIFF image embedding (multi-page, CMYK, direct mapping)
  • Image format auto-detection (PNG/JPEG/WebP/TIFF)
  • Form field JavaScript evaluation & sandboxing
  • Outlines / bookmarks
  • Optional content layers (OCGs)
  • File attachments & watermarks
  • PDF 2.0: associated files (Factur-X), document parts, soft masks
  • Linearization (fast web view)
  • Browser helpers (download, blob, data URL)
  • Service Worker & Web Worker support
  • Batch processing with memory pressure handling
  • Spot colors (Separation) & DeviceN
  • CLI: npx modern-pdf optimize

Why modern-pdf-lib?

modern-pdf-lib pdf-lib
Runtime Node, Deno, Bun, CF Workers, browsers Node, browsers
Module format ESM + CJS CJS (with ESM wrapper)
TypeScript 7.0 strict 3.x
Parse existing PDFs Yes (with decryption) Yes
Text extraction Yes (with positions) No
Encryption AES-256 + RC4 No
Digital signatures PKCS#7, timestamps, CRL/OCSP, LTV, MDP No
Incremental save Signature-preserving, multi-sig chains No
WebP images Lossy, lossless, alpha No
TIFF images Multi-page, CMYK, direct mapping No
JPEG2000 decoding Full JPXDecode (JP2 + J2K) No
Form JavaScript Sandboxed evaluation No
Forms Full (7 field types) Full
PDF/A compliance 1a/1b through 3a/3b/3u + 4/4e/4f No
JSX / VDOM rendering JSX runtime + component renderer No
Accessibility (PDF/UA) Structure tree, checker No
Merge & split Built-in Copy pages only
Annotations 18 types + appearances No
Streaming output ReadableStream No
Layers (OCG) Yes No
Outlines Yes No
Watermarks Yes No
Redaction Yes No
Linearization Yes No
QR codes & barcodes 9 formats (QR, EAN, Code 128, PDF417…) No
Spot / DeviceN colors Separation, multi-ink, conversion No
Header / footer engine Templates, page numbers, dates No
Table layout Spanning, pagination, presets, overflow No
Browser utilities Download, blob, Web Worker, Service Worker No
Image optimization JPEG recompress, dedup, grayscale No
WASM acceleration Optional (compression, PNG, fonts, JBIG2, JPEG) No
Dependencies 1 (fflate) 0
Maintained Active Inactive since 2021

Runtimes

Runtime Version Status
Node.js 26.4+ Fully supported
Deno 1.40+ Fully supported
Bun 1.0+ Fully supported
Cloudflare Workers — Fully supported
Chrome / Edge 109+ Fully supported
Firefox 115+ Fully supported
Safari 16.4+ Fully supported

API Surface

Document — create, load, save, metadata
import { createPdf, loadPdf, PageSizes } from 'modern-pdf-lib';

// Create from scratch
const doc = createPdf();
doc.setTitle('Invoice #1042');
doc.setLanguage('en');

// Load existing
const existing = await loadPdf(pdfBytes, { password: 'secret' });

// Save
const bytes = await doc.save();
const stream = doc.saveAsStream();
Pages — draw text, images, shapes, SVG
const page = doc.addPage(PageSizes.LETTER);
const font = await doc.embedFont(StandardFonts.Helvetica);

page.drawText('Hello', { x: 50, y: 700, size: 24, font });
page.drawImage(imageRef, { x: 50, y: 400, width: 200, height: 200 });
page.drawRectangle({ x: 50, y: 300, width: 100, height: 50, color: rgb(0, 0.5, 1) });
page.drawCircle({ x: 200, y: 325, radius: 25 });
page.drawSvgPath('M 0 0 L 100 0 L 50 80 Z', { x: 300, y: 300 });
Fonts — embed, subset, standard 14
// Standard fonts (no glyph data embedded — just a font dictionary)
const helvetica = await doc.embedFont(StandardFonts.Helvetica);

// Custom TrueType / OpenType
const fontBytes = await readFile('Inter.ttf');
const inter = await doc.embedFont(fontBytes, { subset: true });

page.drawText('Custom font', { x: 50, y: 500, font: inter, size: 18 });
Forms — fill, create, flatten
const form = doc.getForm();

form.getTextField('name').setText('Jane Doe');
form.getCheckbox('agree').check();
form.getDropdown('country').select('Canada');

form.flatten(); // Burn values into page content
Merge & Split
import { loadPdf, mergePdfs, splitPdf } from 'modern-pdf-lib';

// mergePdfs / splitPdf operate on PdfDocument objects — load the bytes first.
const merged = await mergePdfs([await loadPdf(pdf1Bytes), await loadPdf(pdf2Bytes)]);
const pages = await splitPdf(await loadPdf(pdfBytes), [
  [0, 4],   // Pages 1-5 (zero-based, inclusive)
  [5, 9],   // Pages 6-10
]);
Encryption — AES-256, RC4, permissions
// Configure encryption with doc.encrypt(), then save().
await doc.encrypt({
  userPassword: 'reader',
  ownerPassword: 'admin',
  permissions: { printing: true, copying: false },
});
const bytes = await doc.save();
Digital Signatures
import { signPdf, verifySignatures } from 'modern-pdf-lib';

const signed = await signPdf(pdfBytes, 'Signature1', {
  certificate: certDer,
  privateKey: keyDer,
  reason: 'Approved',
  appearance: {                    // optional visible signature
    rect: [50, 50, 200, 80],
    fontSize: 10,
  },
});

const results = await verifySignatures(signed);
Text Extraction
import { loadPdf, parseContentStream, extractTextWithPositions } from 'modern-pdf-lib';

const doc = await loadPdf(pdfBytes);
const page = doc.getPage(0);
const operators = parseContentStream(page.getContentStream());
const items = extractTextWithPositions(operators);

for (const item of items) {
  console.log(`"${item.text}" at (${item.x}, ${item.y})`);
}
Image Optimization — batch compress, deduplicate, CLI
import { loadPdf, initWasm, optimizeAllImages, deduplicateImages } from 'modern-pdf-lib';

await initWasm({ jpeg: true });

const doc = await loadPdf(pdfBytes);

// Deduplicate identical images
const dedupReport = deduplicateImages(doc);

// Optimize all images (JPEG recompression)
const report = await optimizeAllImages(doc, {
  quality: 75,
  progressive: true,
  autoGrayscale: true,
});

console.log(`${report.optimizedImages}/${report.totalImages} images optimized`);
console.log(`Savings: ${report.savings.toFixed(1)}%`);

const optimized = await doc.save();

CLI:

npx modern-pdf optimize report.pdf report-opt.pdf --quality 60 --grayscale --dedup -v
Tables — layout engine with spanning, pagination, presets
import { createPdf, PageSizes, professionalPreset, applyPreset } from 'modern-pdf-lib';

const doc = createPdf();
const page = doc.addPage(PageSizes.A4);

page.drawTable(applyPreset(professionalPreset(), {
  x: 50,
  y: 750,
  width: 495,
  headerRows: 1,
  rows: [
    { cells: ['Product', 'Qty', 'Price', 'Total'] },
    { cells: ['Widget A', '10', '$5.00', '$50.00'] },
    { cells: ['Widget B', '25', '$3.50', '$87.50'] },
    { cells: [{ content: 'Grand Total', colSpan: 3, align: 'right' }, '$137.50'] },
  ],
  columns: [{ flex: 2 }, { width: 60 }, { width: 80 }, { width: 80, align: 'right' }],
}));
QR Codes & Barcodes — 9 formats
import { createPdf, PageSizes } from 'modern-pdf-lib';

const doc = createPdf();
const page = doc.addPage(PageSizes.A4);

// QR code
page.drawQrCode('https://example.com', { x: 50, y: 700, size: 120 });

// Barcodes (Code 128, EAN-13, UPC-A, Code 39, ITF, PDF417, Data Matrix)
import { encodeCode128, encodeEan13, renderStyledBarcode } from 'modern-pdf-lib';

const barcode = encodeCode128('ABC-12345');
const ops = renderStyledBarcode(barcode, 50, 500, 'ABC-12345', { height: 60 });
PDF/A & Accessibility
import { enforcePdfA, checkAccessibility } from 'modern-pdf-lib';

// Enforce PDF/A-2b compliance
const archival = enforcePdfA(pdfBytes, '2b');

// Check accessibility
const issues = checkAccessibility(doc);
for (const issue of issues) {
  console.log(`[${issue.severity}] ${issue.code}: ${issue.message}`);
}

Install

# npm
npm install modern-pdf-lib

# pnpm
pnpm add modern-pdf-lib

# yarn
yarn add modern-pdf-lib

# bun
bun add modern-pdf-lib

# deno
import { createPdf } from 'npm:modern-pdf-lib';

WASM Acceleration

All WASM modules are optional. Without them, identical output is produced using pure-JS fallbacks.

import { initWasm } from 'modern-pdf-lib';

await initWasm({
  deflate: true,   // Faster compression
  png: true,       // Faster PNG decoding
  fonts: true,     // Faster font subsetting
  jpeg: true,      // JPEG encode/decode for image optimization
});
Module Purpose Speedup
libdeflate Stream compression ~2x
png PNG image decoding ~5x
ttf Font parsing (feeds the JS subsetter) ~3x
shaping Complex script layout ~10x
jbig2 JBIG2 bilevel image decoding ~3x
jpeg JPEG encode/decode for image optimization Required

Project Structure

modern-pdf-lib/
  src/
    core/           PDF document model, objects, writer, pages
    parser/         PDF loading, text extraction, content streams
    render/         Content-stream interpreter, rasterizer, Canvas, thumbnails, OCR, redaction
    form/           AcroForm fields (7 types), appearances, JSON Schema forms
    annotation/     18 annotation types + appearance generators
    accessibility/  Structure tree, marked content, PDF/UA-1 & UA-2 checkers, auto-tagging
    compliance/     PDF/A & PDF/X validation, PDF/A-4, Factur-X / e-invoicing
    signature/      PKCS#7 signatures, timestamps, verification, CRL/OCSP, LTV
    security/       Threat scanner, sanitizer, redaction verifier, encryption inspector
    crypto/         AES-256, RC4, MD5, SHA-256/384/512
    compression/    Deflate (fflate + optional WASM)
    assets/         Font metrics/embed/subset, image embed, SVG
    text/           BiDi (UAX #9) text ordering
    color/          Color conversion & ICC transforms
    barcode/        QR, Code 128, EAN, UPC, Code 39, ITF, PDF417, Data Matrix
    layout/         Tables, headers/footers, Knuth-Plass text layout, hyphenation
    jsx/            JSX runtime + renderJsxToPdf component renderer
    browser/        Download helpers, Service Worker, Web Worker
    runtime/        Server adapters, capability detection, memory budget
    batch/          Batch processing with memory pressure handling
    layers/         Optional content groups (OCG)
    outline/        Bookmarks / document outline
    metadata/       XMP metadata, viewer preferences
    plugins/        Plugin manager & hooks
    wasm/           Rust crate sources (6 modules)
    cli/            CLI tool (modern-pdf optimize)
  tests/            6,969 tests across 323 suites
  docs/             VitePress documentation

Contributing

git clone https://github.com/ABCrimson/modern-pdf-lib.git
cd modern-pdf-lib
npm install
npm test          # 6,969 tests
npm run typecheck # TypeScript 7.0 strict
npm run build     # ESM + CJS + declarations

License

MIT © 2026

About

A modern, WASM-accelerated PDF creation engine for every JavaScript runtime

Resources

Contributing

Security policy

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages