npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pdfnative

v1.8.0

Published

Zero-dependency native PDF library: generate, parse, merge/split, extract text with positions, fill & flatten AcroForms, decrypt and re-encrypt (RC4, AES-128/256), and draw native vector charts (stacked/area/scatter, log & time axes). 27 scripts (Arabic,

Readme

pdfnative

CI CodeQL npm version npm downloads bundle size zero dependencies TypeScript License: MIT npm provenance website pdfnative-mcp pdfnative-cli pdfnative-react

Pure native PDF generation library — zero vendor dependencies. Conforms to ISO 32000-1 (PDF 1.7).

Ecosystem

pdfnative ships as four coordinated packages — pick whichever entry point fits your workflow:

| Package | Latest | Use it for | |---|:---:|---| | pdfnative | v1.8.0 | The library itself — call from Node, browsers, Workers, Deno, Bun. | | pdfnative-cli | v1.4.0 | Render JSON → PDF, sign with the complete PAdES ladder (sign --timestamp B-T, ltv B-LT with air-gapped collect → embed, doc-timestamp B-LTA; RSA-SHA256/384/512 + ECDSA, native constant-time crypto by default), inspect, verify, compare (CI text + structure diff), signature-safe metadata edits, merge / split / extract pages, annotate, govern (AI-governance / HITL gate), declarative batch --manifest pipelines, and emit JSON Schemas from the shell. Pins pdfnative ^1.7.0: 27 scripts + COLRv1 emoji, --font math, charts v2, print production, render --strict PDF/A gating, and an agent-native --json/E_*/--dry-run/--summary contract. Node ≥ 22. | | pdfnative-mcp | v1.6.0 | Use pdfnative from Claude Desktop, Cursor, Continue, Zed (or any MCP client, stdio or HTTP) — 28 production tools spanning the engine's full document model: all 13 block kinds in generate_basic_pdf, layout options, build-time encrypt that keeps the AcroForm, image watermarks, print production (page boxes, bleed, marks, /UserUnit, OutputIntent), charts v2 (stacked / area / scatter, dual axis, log & time scales), the complete PAdES ladder B-B → B-LTA (sign_pdf with RFC 3161 timestamps, add_ltv, timestamp_pdf, verify_pdf ltv: true), update_metadata, the read-only inspect_layout pagination preview, honest PDF/A (embedFonts / strict / diagnostics), six MCP prompts, token-frugal read modes (verbosity / fields), the network-free draft_governance_issue (AI-governance / HITL), and the MCP 2026-07-28 spec with automatic legacy fallback. No outbound request by default — the only permitted egress is operator-configured TSA / OCSP / CRL. Pins pdfnative ^1.7.0. | | pdfnative-react | v1.2.0 | Write PDFs as declarative JSX — <Document>, <Page>, <Table>, <Barcode>, <Svg>, <FormField>… compiled on-device to pdfnative blocks by a custom React 19 reconciler. Charts v2 (9 kinds, dual axes, log/time scales), print production (<Document print>), the PDF/A diagnostics channel (layout.strict / onDiagnostic), HTTP caching on renderToResponse (etag / cacheControl), 25 lint rules, client hooks & components (usePdf, PDFViewer, PDFDownloadLink), and a versioned DocSpec grammar (docSpecSchema()) for AI agents. Peer: pdfnative ^1.7.0, React ^19.0.0, Node ≥22. (A 1.6 engine would throw mid-render on the charts-v2 fields.) |

npm install pdfnative                 # library
npm install pdfnative pdfnative-react react   # React renderer (pdfnative + React 19 peers)
npm install -g pdfnative-cli          # CLI
npm install -g pdfnative-mcp          # MCP server

Detailed docs: CLI guide · MCP guide · React guide · Onboarding cheatsheet.

Highlights

  • Zero dependencies — built from scratch in pure TypeScript. Zero runtime dependencies, tree-shakeable, auditable
  • Conforms to ISO 32000-1 — valid xref tables, /Info metadata, proper font embedding
  • 27 Unicode scripts — Thai, Japanese, Chinese (SC), Korean, Greek, Devanagari, Telugu, Turkish, Vietnamese, Polish, Arabic, Hebrew, Cyrillic, Georgian, Armenian, Bengali, Tamil, Sinhala, Tibetan, Khmer, Myanmar, Lao, Tai Tham (Lanna), New Tai Lue, Tai Le, Cham, Ethiopic
  • Universal Shaping Engine — cluster categories derived from the Unicode Character Database, driving Tai Tham and Cham
  • Thai and Lao OpenType shaping — GSUB substitution + GPOS mark-to-base + mark-to-mark positioning
  • Arabic positional shaping — GSUB isolated/initial/medial/final forms + lam-alef ligatures
  • BiDi text layout — Unicode Bidirectional Algorithm (UAX #9) with isolates (LRI/RLI/FSI/PDI) and explicit embeddings (LRE/RLE/LRO/RLO/PDF) including character-level X4–X5 overrides (v1.3.0). v1.7.0 implements I1/I2 even embedding levels so digit runs (European, Arabic-Indic, Extended Arabic-Indic) keep logical order in RTL text, and full rule-L4 glyph mirroring through the complete 428-pair BidiMirroring.txt table
  • Indic OpenType engine (v1.8.0) — Devanagari, Bengali, Tamil, Telugu and Sinhala share one engine that applies the font's own GSUB features per syllable in specification order (rphf, half, blwf, pstf, vatu, cjct, pres … haln, contextual lookups included) and attaches every vowel sign to the anchor its font declares: reph over the consonant after the base, half forms, subjoined consonants, pre-base matras in front. Fed by the otl layout tables every font module now carries; the words of a rendering report on the Hindi, Tamil and Telugu samples are golden tests on the bundled fonts
  • Latin combining marks (v1.8.0) — free-standing marks (Yoruba ẹ́ ọ̀, Igbo ị́, NFD accents, Greek and Cyrillic diacritics) compose through the font's ccmp and GPOS anchors; Hausa, Yoruba, Igbo and Swahili render on the bundled latin module with no new font
  • USE-lite shaping — classifyUseCategory / classifyClusters classify joiners for the Indic engine and the Khmer, Myanmar and Tibetan shapers (v1.3.0)
  • Colour emoji (COLRv1) — opt-in Noto Color Emoji subset (expanded to 1167 glyphs in v1.6.0, ~4.5 MB with the v1.7.0 sequence ligatures, incl. the complete Transport & Map block); solid + linear + radial gradient layers rendered as native PDF Form XObjects; monochrome fallback when not registered (v1.3.0). Variation selectors, ZWJ/ZWNJ, and skin-tone modifiers no longer leave tofu, and glyph /BBox is computed from contour bounds so emoji are never clipped (v1.3.0). Advanced compositing (v1.4.0): COLRv1 sweep (conic) gradients render as native flat-shaded wedges, and PaintComposite separable blend modes (Multiply, Screen, Overlay, Darken, Lighten, …) map to PDF /BM ExtGState; structural Porter-Duff modes fall back to monochrome. Flag & ZWJ sequences (v1.7.0): 51 flags + 22 ZWJ sequences (families, professions, rainbow/pirate flags, …) resolve through the source font's GSUB into single colour ligature glyphs with a longest-match pre-pass — both VS-16 spellings match, uncovered sequences degrade to the historical per-codepoint rendering, and the CLI bundles any custom set (--sequences, --sequence-list, skin tones included). Skin tones, transforms and masks (v1.8.0): 30 gestures and people bundled in all five tones (1189 glyphs + 223 sequences, ~4.9 MB); every COLRv1 transform and variable paint is read, and SRC_IN/DEST_IN masks render as clipping paths, so flags keep their shaded wave. Guide →
  • Multi-font fallback — automatic cross-script font switching with continuation bias
  • TTF subsetting — only used glyphs embedded (dramatic file size reduction)
  • Tagged PDF / PDF/A — structure tree, /ActualText, XMP metadata, sRGB OutputIntent (PDF/A-1b, 2b, 2u, 3b with embedded file attachments). Conformance guards (v1.7.0): configurations that would break the declared PDF/A level (no embedded fonts, DeviceCMYK images) surface a diagnostic — console.warn by default, a custom onDiagnostic sink, or a thrown error under strict: true. CMYK intents (v1.8.0): CMYK and Gray OutputIntent profiles, with RGB content kept conforming through a calibrated /DefaultRGB. Guide →
  • PDF Encryption (round-trip) — write AES-128 (V4/R4) and AES-256 (V5/R6) encrypted PDFs (RC4 is never emitted), and read all of AES-128, AES-256, and legacy RC4 (V1–V4); owner + user passwords, granular permissions. v1.6.0 adds a Standard Security Handler decryptor — openPdf(bytes, { password }) decrypts transparently, the merge/split API ingests encrypted sources and re-encrypts its output (MergeOptions.encrypt, AES only, fresh keys) — closing the full open → edit → re-secure round trip. Guide →
  • Native vector charts (v1.6.0, charts v2 in v1.7.0) — bar, horizontal-bar, line, pie, donut, stacked bars, area, and scatter chart blocks rendered as pure PDF path operators (zero deps, no rasterisation); multi-series, legends, "nice" axis ticks, negative values, tagged /Figure + alt text. v1.7.0 adds a secondary right axis, log and UTC-deterministic time scales, per-point data labels, and x-label collision handling (automatic stride + labelStride / labelRotation). Guide →
  • Text extraction (v1.6.0) — extractText() decodes page content streams into per-page reading-order Unicode text plus optional positioned runs; /ToUnicode CMap, /Encoding /Differences, and WinAnsi/MacRoman decoding; works on encrypted documents ({ password }); hard maxTextLength memory cap for untrusted input. Guide →
  • Free-form document builder — headings, paragraphs, lists (incl. nested / hierarchical bullet & numbered lists, v1.4.0), tables, images, barcodes, SVG paths, form fields, spacers, page breaks, table of contents. Configurable block limit via layout.maxBlocks (default 100 000) for very large reports (v1.3.0)
  • Smart tables — multi-page slicing with repeated headers, auto-wrap on column overflow, zebra striping, captions, and smart auto-fit columns (v1.2.0), plus per-cell borders (cellBorders) and vertical alignment (cellVAlign / ColumnDef.vAlign, v1.4.0). Guide →
  • Barcode & QR code generation — Code 128, EAN-13, QR Code, Data Matrix, PDF417 — pure PDF path operators (no images)
  • SVG rendering — path, rect, circle, ellipse, line, polyline, polygon as native PDF operators, plus <text> elements rendered as upright PDF text with x/y positioning and text-anchor (start/middle/end) support (v1.5.0)
  • AcroForm fields — text, multiline, checkbox, radio, dropdown, listbox with appearance streams (ISO 32000-1 §12.7). v1.6.0 adds fill & flatten of existing forms: readFormFields(), fillForm() (regenerates appearances), and flattenForm() — non-destructive incremental update that preserves prior signatures, including on encrypted documents (appended objects are encrypted under the document's existing scheme). Guide →
  • Digital signatures — CMS/PKCS#7 detached signatures with RSA (SHA-256/384/512, v1.7.0) + ECDSA-SHA256 (P-256) and X.509 parsing (ISO 32000-1 §12.8). One-call placeholder injection via addSignaturePlaceholder() (v1.2.0). Pluggable native crypto provider (setCryptoProvider() / PdfSignOptions.provider, v1.4.0) for constant-time, hardware-backed signing (node:crypto / Web Crypto / HSM). v1.7.0: PAdES baseline profile (profile: 'pades' — ESS signing-certificate-v2, ETSI.CAdES.detached), multiple signatures (allowMultiple + fieldName selector), and listSignatures() inspection. Guide →
  • Print production (v1.7.0) — bleed/trim/art/crop page boxes (layout.print, with a one-line bleed shorthand), crop & registration marks drawn as pure vector operators outside the TrimBox, /Trapped metadata with XMP parity, print-dialog defaults (duplex, tray pick, page range, copies), caller-supplied OutputIntent ICC profile (tagged mode), and large-format /UserUnit (banners, plans). Boxes survive mergePdfs/splitPdf. Byte-identical output when unused. CMYK & PDF/X-4 (v1.8.0): CMYK colours on every colour option ([c, m, y, k] in percent), CMYK and Gray OutputIntents with RGB content kept conforming, marks in the all-separation registration colour and clear of both the trim line and the sheet edge, opt-in colour control bars (marks: { colourBars: true }), marks tagged as a /Page artifact in accessible output, a pdfx: 'pdfx4' conformance claim, and validatePdfX() to check it. Guide →
  • Typography (v1.8.0) — paragraphs that break across pages under widow and orphan rules, headings kept with what they introduce (with a minLines quota), opt-in short-word binding so a line never ends on "a" or "I", align: 'justify' written as one TJ array per line (spaces preserved for search and extraction), optical margin alignment, soft hyphens plus a setHyphenationProvider() seam with a document language, ISO 80000-1 number–unit binding, French and Canadian-French punctuation spacing (narrow no-break spaces rendered with a registered font), exact Adobe Core 14 metrics, GPOS pair kerning and OpenType single-substitution features (onum, pnum, smcp, …) with a diagnostic when a tag changes nothing. All opt-in under layout.typography; byte-identical when unset. Guide →
  • Long-term validation (LTV, PAdES B-B → B-LTA) (v1.7.0) — RFC 3161 signature timestamps (signPdfBytesWithTimestamp()), embedded revocation material in /DSS + per-signature /VRI (addValidationInfo() — OCSP RFC 6960 + CRL RFC 5280), and document timestamps (addDocumentTimestamp()). Network transport is injected (TimestampProvider / RevocationProvider) — the engine stays offline and zero-dependency; rejected or tampered TSA tokens are never embedded. Guide →
  • Streaming output — AsyncGenerator-based progressive PDF emission with configurable chunk size, object-boundary page-by-page streaming, and true constant-memory streaming (buildDocumentPDFStreamTrue(), v1.3.0) where the full PDF binary never materialises. One-call streamToFile() drains any stream to disk with back-pressure and AbortSignal support (v1.4.0). Guide →
  • Document outline & page labels — nested bookmarks (/Outlines tree, with bold/italic/colour, collapsible nodes via open: false, explicit or outline: 'auto' from headings) and logical page numbering (/PageLabels: decimal, roman, alpha, prefixes, custom start) (v1.4.0). Guide →
  • Viewer preferences — PdfLayoutOptions.viewerPreferences controls initial /PageLayout & /PageMode plus the /ViewerPreferences dict (hide toolbar/menubar, fit/center window, display doc title, non-full-screen mode, reading direction, print scaling) — PDF/A-safe (v1.4.0). v1.7.0 adds the print-dialog defaults: duplex, pickTrayByPDFSize, printPageRange, numCopies. Guide →
  • Font-data validator — opt-in validateFontData() structurally checks custom font modules (SFNT magic, base64 integrity, cmap coverage, glyph-id range, width array, finite metrics) and returns { valid, errors, warnings } (v1.4.0). Guide →
  • PDF parser & modifier — read existing PDFs (tokenizer, xref, object parser, FlateDecode inflate) + incremental modification. Read-only PDF/UA structural checker validatePdfUA() (ISO 14289-1: MarkInfo, StructTree, ParentTree, Lang, per-page MCID uniqueness) (v1.3.0), and its PDF/X-4 counterpart validatePdfX() (ISO 15930-7: header, XMP identification, OutputIntent profile, page boxes, embedded fonts, annotations, device colour) (v1.8.0). Page-tree manipulation (v1.4.0): mergePdfs(), splitPdf(), extractPages() rebuild a clean object graph (inherited attributes resolved, annotations/signatures optionally dropped, deterministic trailer /ID, bounded-depth copy, 256 MiB output cap via maxOutputSize). Round-trip readers (v1.5.0): getPageLabels() parses /PageLabels back into a typed PageLabelRange[]; getAnnotations() / getPageRef() read page annotations, and PdfModifier.addAnnotation() injects new ones incrementally. v1.6.0: a Standard Security Handler decryptor (openPdf(bytes, { password }), RC4/AES-128/AES-256) lets the reader and page-tree API ingest encrypted sources, and constant-memory streaming variants streamMergedPdfs() / streamSplitPdf() / streamExtractPages() emit merges/splits in fixed-size chunks (byte-identical to the buffered functions). Guide →
  • Markup annotations — typed annotation model (text, highlight, underline, strikeout, squiggly, square, circle, line, freetext) via buildAnnotation() / buildAnnotationBody(), plus PdfReader.getAnnotations() and PdfModifier.addAnnotation() for round-trip read/write (v1.5.0); v1.6.0 lets addAnnotation() operate on encrypted documents (RC4/AES sources, annotations stored encrypted). Guide →
  • Layout debug & inspection — opt-in layout: { debug: true } overlays margin / content / cell boxes for visual layout debugging; inspectDocumentLayout() returns a programmatic per-page block-geometry report. Byte-identical when debug is off (v1.5.0). Guide →
  • Math & technical symbols — bundleable math font under lang 'math'; mathematical operators, Greek, arrows, and technical symbols route automatically via script detection (v1.5.0)
  • Font-data tooling — pdfnative/tools exposes compileFontData() / parseFontData() to build and introspect font-data modules programmatically (v1.5.0)
  • Image embedding — JPEG (DCTDecode) and PNG (FlateDecode) with auto-scaling and alignment
  • Hyperlinks — PDF link annotations (/URI) with URL validation, blue underlined text, tagged /Link
  • Header/footer templates — configurable PageTemplate with left/center/right zones and {page}/{pages}/{date}/{title} placeholders
  • Watermarks — text and image overlays with configurable opacity, rotation, and position (background/foreground)
  • Table of contents — auto-generated TOC with internal /GoTo links, dot leaders, and page numbers
  • FlateDecode compression — zlib stream compression (50–90% size reduction), zero-dependency, platform-native
  • Web Worker support — off-main-thread generation for large datasets
  • Tree-shakeable — ESM + CJS dual build with TypeScript declarations
  • Heavily tested — 3824+ tests across 160 files, fuzz suite, dual-mode visual-regression suite, performance benchmarks; 91.5 % statement coverage measured at the v1.8.0 release, with CI enforcing ≥88% statements / 80% branches / 85% functions / 90% lines (vitest.config.ts)
  • NPM provenance — signed builds via GitHub Actions OIDC
  • On-device generation — runs in Node, browsers, Workers, Deno, Bun. No SaaS round-trip; documents never leave the calling process unless your application explicitly sends them
  • No telemetry, no network calls — verifiable in source. The library never opens a socket, fetches remote fonts, or phones home
  • AI client integration — use pdfnative from Claude Desktop, Cursor, Continue, and Zed via pdfnative-mcp — 28 production tools (generate, tables, barcodes, forms, sign with the full PAdES ladder, verify, validate, attachments, extraction, inspect, metadata, layout preview, plus page-tree merge_pdfs / split_pdf / extract_pages)
  • Command-line interface — render, sign, verify, inspect, and batch-render PDFs from the shell with pdfnative-cli — zero-config, scriptable, agent-native (--json/E_*/--dry-run), ideal for CI/CD pipelines
  • React renderer — author PDFs as declarative JSX with pdfnative-react: <Document>/<Table>/<Barcode> components, usePdf/PDFViewer client hooks, on-device rendering with no DOM or headless browser

Installation

npm install pdfnative

Requirements: Node.js >= 22 | Modern browsers | Deno | Bun

Documentation

Why pdfnative?

pdfnative was designed for teams that need ISO-compliant, production-grade PDF generation with zero supply-chain risk. Here is how it compares to other popular JavaScript PDF libraries:

| Feature | pdfnative | jsPDF | pdfkit | pdf-lib | pdfmake | |---------|:---------:|:-----:|:------:|:-------:|:------:| | Runtime dependencies | 0 | 3 | 6 | 4 | 3 | | TypeScript declarations | Built-in | Built-in | @types/* | Built-in | @types/* | | PDF/A (ISO 19005) | 1b, 2b, 2u, 3b | — | — | — | — | | Tagged PDF / PDF/UA | ✅ | — | ✅ | — | — | | Encryption (read + write) | AES-128/256 + RC4 read | write (RC4) | write | — | write | | Complex text shaping (GSUB/GPOS) | ✅ Thai, Arabic, Devanagari, Bengali, Tamil, Telugu, Sinhala, Khmer, Myanmar, Tibetan, Lao, USE, Latin marks | — | Via fontkit | Via @pdf-lib/fontkit | Via pdfkit | | BiDi (RTL) layout | ✅ | — | — | — | — | | Modify existing PDFs | ✅ (incremental) | — | — | ✅ | — | | Forms (create + fill + flatten) | ✅ all three | create | create | create + fill | — | | Native charts (vector) | ✅ 9 kinds incl. stacked/area/scatter | — | — | — | — | | Digital signatures | ✅ (RSA + ECDSA, PAdES) | — | — | — | — | | LTV / timestamps (PAdES B-LTA) | ✅ RFC 3161 + /DSS | — | — | — | — | | Print production (bleed/trim boxes, marks) | ✅ | — | — | — | — | | Barcode / QR code (native) | ✅ 5 formats | — | — | — | QR | | SVG path rendering | ✅ | Plugin | ✅ | Paths only | ✅ | | Streaming output | ✅ | — | ✅ | — | ✅ | | PDF parser | ✅ | — | — | ✅ | — | | Tree-shakeable (ESM) | ✅ | — | — | ✅ | — | | NPM provenance (SLSA) | ✅ | — | — | — | ✅ |

Data sources: npm registry metadata and official README/documentation for each library, compared on 2026-07-28 (pdfkit 0.19.1, jsPDF 4.2.1, pdfmake 0.3.11, pdf-lib 1.17.1 — see docs/data/comparison-2026-07-28.json). Dependency counts reflect direct dependencies listed in each package's published manifest. "—" means the feature is not supported or not documented. Feature claims about third-party libraries are based on their public documentation and may not reflect the latest version — please verify against current releases. Sample PDFs validate with veraPDF (PDF/A) and Adobe Acrobat.

When to choose another library: You need advanced vector graphics (complex gradients, arbitrary transforms), rich interactive form scripting (JavaScript actions), or mature ecosystem integrations with existing toolchains.

When to choose pdfnative: You need zero-dependency PDF generation with ISO archival compliance (PDF/A), accessibility (tagged PDF), AES encryption, digital signatures, multi-script Unicode support — particularly Arabic/Hebrew BiDi and Thai GSUB/GPOS shaping — form fields, barcode generation, SVG rendering, or the ability to parse and incrementally modify existing PDFs.

Quick Start

import { buildPDFBytes, downloadBlob } from 'pdfnative';

const pdf = buildPDFBytes({
  title: 'Monthly Report',
  infoItems: [
    { label: 'Period', value: 'January 2026' },
    { label: 'Account', value: 'Main Account' },
  ],
  balanceText: 'Balance: $1,234.56',
  countText: '42 transactions',
  headers: ['Date', 'Description', 'Category', 'Amount', 'Status'],
  rows: [
    { cells: ['01/15', 'Grocery Store', 'Food', '-$45.00', ''], type: 'debit', pointed: false },
    { cells: ['01/16', 'Salary', 'Income', '+$3,000.00', 'X'], type: 'credit', pointed: true },
  ],
  footerText: 'Generated by MyApp',
});

// Browser: trigger download
downloadBlob(pdf, 'report.pdf');

// Node.js: write to file
import { writeFileSync } from 'fs';
writeFileSync('report.pdf', pdf);

Document Builder

Build free-form documents with headings, paragraphs, lists, tables, images, barcodes, and more:

import { buildDocumentPDFBytes } from 'pdfnative';

const pdf = buildDocumentPDFBytes({
  title: 'Project Report',
  blocks: [
    { type: 'toc' },
    { type: 'heading', text: 'Executive Summary', level: 1 },
    { type: 'paragraph', text: 'This quarter saw strong growth across all divisions...' },
    { type: 'image', data: jpegBytes, width: 400, align: 'center', alt: 'Revenue chart' },
    { type: 'list', items: ['Revenue up 15%', 'Costs down 8%', 'Net profit +23%'], style: 'bullet' },
    { type: 'table', headers: ['Q1', 'Q2', 'Q3', 'Q4'], rows: [
      { cells: ['$1.2M', '$1.4M', '$1.6M', '$1.8M'], type: 'credit', pointed: false },
    ]},
    { type: 'spacer', height: 20 },
    { type: 'heading', text: 'Next Steps', level: 2 },
    { type: 'paragraph', text: 'Focus areas for next quarter include...', align: 'left' },
    { type: 'link', text: 'View full report online', url: 'https://example.com/report' },
    { type: 'barcode', format: 'qr', data: 'https://example.com/report', align: 'center' },
  ],
  footerText: 'Confidential',
}, {
  headerTemplate: { center: 'Project Report', right: '{date}' },
  footerTemplate: { left: 'Confidential', right: 'Page {page} of {pages}' },
});

Unicode Font Support

For non-Latin scripts, register font data loaders (lazy-loaded on demand):

import { registerFonts, loadFontData, buildPDFBytes } from 'pdfnative';

registerFonts({
  th: () => import('pdfnative/fonts/noto-thai-data.js'),
  ja: () => import('pdfnative/fonts/noto-jp-data.js'),
  zh: () => import('pdfnative/fonts/noto-sc-data.js'),
  ko: () => import('pdfnative/fonts/noto-kr-data.js'),
  el: () => import('pdfnative/fonts/noto-greek-data.js'),
  hi: () => import('pdfnative/fonts/noto-devanagari-data.js'),
  tr: () => import('pdfnative/fonts/noto-turkish-data.js'),
  vi: () => import('pdfnative/fonts/noto-vietnamese-data.js'),
  pl: () => import('pdfnative/fonts/noto-polish-data.js'),
  ar: () => import('pdfnative/fonts/noto-arabic-data.js'),
  he: () => import('pdfnative/fonts/noto-hebrew-data.js'),
  ru: () => import('pdfnative/fonts/noto-cyrillic-data.js'),
  ka: () => import('pdfnative/fonts/noto-georgian-data.js'),
  hy: () => import('pdfnative/fonts/noto-armenian-data.js'),
  bn: () => import('pdfnative/fonts/noto-bengali-data.js'),
  ta: () => import('pdfnative/fonts/noto-tamil-data.js'),
  te: () => import('pdfnative/fonts/noto-telugu-data.js'), // v1.3.0
  si: () => import('pdfnative/fonts/noto-sinhala-data.js'), // v1.3.0
  bo: () => import('pdfnative/fonts/noto-tibetan-data.js'), // v1.3.0
  km: () => import('pdfnative/fonts/noto-khmer-data.js'), // v1.3.0
  my: () => import('pdfnative/fonts/noto-myanmar-data.js'), // v1.3.0
  am: () => import('pdfnative/fonts/noto-ethiopic-data.js'), // v1.3.0
  // v1.1.0+ — optional Latin fallback for PDF/A documents with curly quotes,
  // em-dash, ellipsis, etc. (activates automatically when needed). Since
  // v1.8.0 it also carries Hausa ɓ ɗ ƙ ƴ, Yoruba and Igbo tone marks (ẹ́ ọ̀ ị́)
  // and Swahili — no separate module or lang key for those languages:
  latin: () => import('pdfnative/fonts/noto-sans-data.js'),
  // v1.1.0+ — optional monochrome emoji:
  emoji: () => import('pdfnative/fonts/noto-emoji-data.js'),
});

const thaiFont = await loadFontData('th');

const pdf = buildPDFBytes({
  title: 'รายงานประจำเดือน',
  // ... other params
  fontEntries: thaiFont ? [{ fontData: thaiFont, fontRef: '/F3', lang: 'th' }] : [],
});

Supported Languages

| Language | Code | Font | Script | |----------|------|------|--------| | Thai | th | Noto Sans Thai | GSUB + GPOS shaping | | Japanese | ja | Noto Sans JP | CJK ideographs + kana | | Chinese (Simplified) | zh | Noto Sans SC | CJK ideographs | | Korean | ko | Noto Sans KR | Hangul syllables | | Greek | el | Noto Sans Greek | Greek alphabet | | Hindi (Devanagari) | hi | Noto Sans Devanagari | Indic OpenType engine — conjuncts, reph, half forms, matras (v1.8.0) | | Turkish | tr | Noto Sans Turkish | Latin extended (İ/ı) | | Vietnamese | vi | Noto Sans Vietnamese | Latin + combining marks | | Polish | pl | Noto Sans Polish | Latin extended (Ł/ł) | | Arabic | ar | Noto Sans Arabic | GSUB positional shaping | | Hebrew | he | Noto Sans Hebrew | Right-to-left script | | Russian (Cyrillic) | ru | Noto Sans | Cyrillic alphabet | | Georgian | ka | Noto Sans Georgian | Mkhedruli script | | Armenian | hy | Noto Sans Armenian | Armenian alphabet | | Bengali | bn | Noto Sans Bengali | Indic OpenType engine — conjuncts, reph, ya-phala, split vowels (v1.8.0) | | Tamil | ta | Noto Sans Tamil | Indic OpenType engine — ligatures, pre-base and split vowels (v1.8.0) | | Telugu | te | Noto Sans Telugu | Indic OpenType engine — subjoined consonants, vattu (v1.3.0; engine v1.8.0) | | Sinhala | si | Noto Sans Sinhala | Indic OpenType engine — kombuva, rakaransaya, two-part vowels (v1.3.0; engine v1.8.0) | | Hausa | latin | Noto Sans VF | Latin with ɓ ɗ ƙ ƴ ʼ — no dedicated module (v1.8.0) | | Yoruba | latin | Noto Sans VF | Latin with ẹ ọ ṣ and combining tone marks, composed by the Latin-marks shaper (v1.8.0) | | Igbo | latin | Noto Sans VF | Latin with ị ọ ụ ṅ and combining tone marks (v1.8.0) | | Swahili | latin | Noto Sans VF | Plain Latin — renders with the base-14 fonts too (v1.8.0) | | Latin (PDF/A) | latin | Noto Sans VF | WinAnsi-extended Latin (curly quotes, em-dash, ellipsis…) | | Emoji | emoji | Noto Emoji | Monochrome emoji (BMP/SMP, Fitzpatrick, ZWJ, VS-15/16) |

Multi-Font (Mixed Scripts)

Generate PDFs with multiple scripts in the same document:

const fonts = await Promise.all([
  loadFontData('th'),
  loadFontData('ja'),
  loadFontData('zh'),
]);

const fontEntries = fonts
  .filter(Boolean)
  .map((fd, i) => ({ fontData: fd!, fontRef: `/F${3 + i}`, lang: ['th', 'ja', 'zh'][i] }));

const pdf = buildPDFBytes({
  title: 'Multi-Language Report',
  headers: ['Date', 'Description', 'Category', 'Amount', 'Status'],
  rows: [
    { cells: ['01/01', 'English text', 'Test', '+100', 'OK'], type: 'credit', pointed: false },
    { cells: ['01/02', 'ข้อความไทย', 'ทดสอบ', '-50', ''], type: 'debit', pointed: false },
    { cells: ['01/03', '日本語テキスト', 'テスト', '+200', '済'], type: 'credit', pointed: true },
  ],
  // ... other params
  fontEntries,
});

Web Worker (Large Datasets)

import { createPDF } from 'pdfnative';

const pdf = await createPDF(params, {
  workerUrl: new URL('pdfnative/worker', import.meta.url),
  threshold: 500, // use Worker above 500 rows
  timeout: 30000, // Worker timeout in ms (default: 60000)
  onProgress: (percent) => console.log(`${percent}%`),
});

For lower-level control, use generatePDFInWorker directly with WorkerGenerationOptions:

import { generatePDFInWorker } from 'pdfnative';
import type { WorkerGenerationOptions } from 'pdfnative';

const options: WorkerGenerationOptions = {
  timeout: 15000,
  onProgress: (percent) => console.log(`${percent}%`),
};

const pdf = await generatePDFInWorker(workerUrl, params, options);

Layout Customization

const pdf = buildPDFBytes(params, {
  pageWidth: 595.28,   // A4 (default)
  pageHeight: 841.89,  // A4 (default)
  margins: { t: 45, r: 36, b: 35, l: 36 },
  colors: {
    title: '#2563EB',           // hex — primary format
    credit: [15, 145, 121],     // RGB tuple [0–255]
    debit: '0.863 0.149 0.149', // PDF operator string [0.0–1.0]
    // ... see PdfColors type
  },
  columns: [
    { f: 0.15, a: 'l', mx: 12, mxH: 12 },
    { f: 0.35, a: 'l', mx: 50, mxH: 50 },
    { f: 0.20, a: 'r', mx: 20, mxH: 20 },
    { f: 0.30, a: 'r', mx: 30, mxH: 30 },
  ],
});

Color Formats

All color values accept five formats — three RGB, two CMYK (v1.8.0):

| Format | Example | Description | |--------|---------|-------------| | Hex string | '#2563EB' or '#26E' | Primary format — #RRGGBB or #RGB | | RGB tuple | [37, 99, 235] | Array with values 0–255 | | PDF operator | '0.145 0.388 0.922' | Raw PDF RGB string (0.0–1.0) | | CMYK tuple | [100, 60, 0, 10] | Four-element array, ink coverage in percent 0–100 (v1.8.0) | | CMYK operand | '1 0.6 0 0.1' | Raw PDF CMYK string (0.0–1.0) (v1.8.0) |

import { parseColor } from 'pdfnative';

parseColor('#2563EB');           // '0.145 0.388 0.922'
parseColor([37, 99, 235]);       // '0.145 0.388 0.922'
parseColor('0.145 0.388 0.922'); // '0.145 0.388 0.922'
parseColor([0, 0, 0, 100]);      // '0 0 0 1'  (CMYK, v1.8.0)

The component count decides the colour space: three components write rg / RG, four write k / K. All inputs are validated and normalized before interpolation into PDF content streams, preventing operator injection. Under a PDF/A or PDF/X claim whose OutputIntent is not CMYK, a CMYK colour raises PDFA_DEVICE_CMYK_CONTENT / PDFX_DEVICE_CMYK — see the print guide.

Font Sizes

Customize font sizes for each zone (title, info bar, table header, table cells, footer):

const pdf = buildPDFBytes(params, {
  fontSizes: {
    title: 20,   // Title text (default: 16)
    info: 10,    // Info bar items (default: 9)
    th: 9,       // Table header cells (default: 8)
    td: 8,       // Table body cells (default: 7.5)
    ft: 8,       // Footer text (default: 7)
  },
});

| Zone | Key | Default | Description | |------|-----|---------|-------------| | Title | title | 16 | PDF title text | | Info bar | info | 9 | Key-value pairs below title | | Table header | th | 8 | Column header row | | Table cells | td | 7.5 | Data row cells | | Footer | ft | 7 | Page footer text |

All values are in PDF points (1pt = 1/72 inch). Partial overrides are supported — unspecified keys use defaults.

Building Custom Font Data

Obtaining TTF Files

For Noto Sans fonts, download the raw .ttf file directly from the noto-fonts GitHub repository:

  1. Navigate to the font's GitHub repository (e.g., github.com/notofonts/bengali)
  2. Find the TTF file under fonts/NotoSansBengali/unhinted/ttf/ (or similar path)
  3. Click the file, then click "Download raw file" (or use the raw URL)
  4. Save it to fonts/ttf/

No zip download or extraction needed — each TTF is a standalone file you can download directly.

Building the Data Module

Convert any TTF font into an importable data module:

npx pdfnative-build-font fonts/ttf/MyFont.ttf fonts/my-font-data.js

The tool extracts cmap, widths, metrics, GSUB, GPOS, and embeds the raw TTF as base64.

Full colour-emoji coverage (pdfnative-build-emoji-font)

The bundled colour-emoji module (pdfnative/fonts/noto-color-emoji-data.js) ships a lean curated subset to keep the package small. When you need glyphs beyond that subset — up to the full ~3,600-glyph Noto Color Emoji set — a second bundled binary generates a custom data module on demand, so even pdfnative-only users get full coverage without the package ever carrying the ~32 MB source font:

# Download the pinned Noto Color Emoji (SHA-256 verified) and emit every glyph
npx pdfnative-build-emoji-font --download --all --out my-color-emoji-data.js

# …or build from a local TTF, selecting only the glyphs you need
npx pdfnative-build-emoji-font --ttf NotoColorEmoji-Regular.ttf \
  --codepoints "1F600,1F680,2764" --out my-color-emoji-data.js

Select glyphs with --all, --preset, --codepoints, or --ranges, then register the generated module under lang 'emoji'. See the Colour-emoji CLI guide.

Agentic workflows

pdfnative is shaped so an AI agent can do more than call the engine — it can extend it at runtime and feed it content it generated itself, without waiting for a library release. Both patterns use already-shipped, public APIs.

1. Extend the engine at runtime — no release required. The font registry is a runtime API. An agent can compile a TTF/OTF in memory and register it on the spot, so a document renders the moment it needs a new script, symbol set, or brand font:

import { registerFont, loadFontData, buildDocumentPDFBytes } from 'pdfnative';
registerFont('th', () => import('pdfnative/fonts/noto-thai-data.js'));
const th = await loadFontData('th');
if (!th) throw new Error('Thai font failed to load');
const bytes = buildDocumentPDFBytes({
  title: 'Thai demo',
  blocks: [{ type: 'paragraph', text: 'สวัสดีชาวโลก' }],
  fontEntries: [{ fontData: th, fontRef: '/F3', lang: 'th' }], // /F1 and /F2 are reserved
});

This is how the bundled Noto Sans Math font existed as a working runtime pattern before it shipped as a default in v1.5.0. Use compileFontData() to emit a reusable *-data.js module (byte-identical to npx pdfnative-build-font).

2. Embed agent-generated images. Image-generating agents (e.g. Antigravity, ChatGPT, and other multimodal assistants) can pipe a generated PNG/JPEG straight into a document — via the image block (library / CLI) or the embed_image MCP tool. pdfnative parses and embeds it natively (no rasterization) and validates it at the boundary.

Runtime extensibility is not autonomous modification of the published package: the agent extends its own in-process instance; the repository is only ever changed by a human under the AI-governance / human-in-the-loop contract. See the Agentic workflows guide for the full walkthrough.

Visual PDF Inspection

Generate sample PDFs for all supported languages to visually verify output:

npm run test:generate

This creates 292 sample PDFs in test-output/ (git-ignored), organized in 38 categories produced by 49 generators (including charts/ native vector charts, bidi/ Persian and mirroring showcases, signatures/ LTV pipelines, and print/ prepress output added in v1.7.0). See scripts/README.md for the modular generator architecture.

Financial Statements (per language)

| File | Content | |------|---------| | sample-latin.pdf | English / Helvetica | | sample-th.pdf | Thai with GSUB + GPOS shaping | | sample-ja.pdf | Japanese (CJK ideographs) | | sample-zh.pdf | Chinese Simplified | | sample-ko.pdf | Korean (Hangul) | | sample-el.pdf | Greek | | sample-hi.pdf | Hindi (Devanagari) | | sample-tr.pdf | Turkish (İ/ı special casing) | | sample-vi.pdf | Vietnamese (combining marks) | | sample-pl.pdf | Polish (Ł/ł) | | sample-ar.pdf | Arabic (RTL, positional shaping) | | sample-he.pdf | Hebrew (RTL) | | sample-ru.pdf | Russian (Cyrillic) | | sample-ka.pdf | Georgian (Mkhedruli) | | sample-hy.pdf | Armenian | | sample-bn.pdf | Bengali (GSUB conjuncts + GPOS marks) | | sample-ta.pdf | Tamil (GSUB + split vowel decomposition) | | sample-multi.pdf | Mixed: all 27 scripts in one PDF | | sample-pagination.pdf | 200 rows, multi-page layout |

Diverse Use Cases (non-financial)

| File | Content | |------|---------| | diverse-student-transcript.pdf | University academic transcript (Latin) | | diverse-recipe-th.pdf | Thai recipe — Tom Yum Goong ingredients (Thai) | | diverse-server-ja.pdf | Server monitoring dashboard (Japanese) | | diverse-inventory-zh.pdf | Warehouse product inventory (Chinese) | | diverse-sports-ko.pdf | K-League football standings (Korean) | | diverse-library-el.pdf | Classical Greek library catalog (Greek) | | diverse-medical-hi.pdf | Blood test lab results (Hindi) | | diverse-menu-tr.pdf | Turkish restaurant dinner menu (Turkish) | | diverse-weather-vi.pdf | Weekly weather forecast — Hanoi (Vietnamese) | | diverse-train-pl.pdf | Train schedule — Warsaw (Polish) | | diverse-marketplace-ar.pdf | Gold marketplace catalog — Dubai (Arabic) | | diverse-museum-he.pdf | Museum exhibition catalog — Jerusalem (Hebrew) |

Alphabet / Character Coverage

| File | Content | |------|---------| | alphabet-thai.pdf | 44 consonants, vowels, tone marks, digits | | alphabet-japanese.pdf | Hiragana, Katakana, Kanji numerals & common | | alphabet-chinese.pdf | 121 characters by category (HSK frequency) | | alphabet-korean.pdf | Hangul jamo, syllables, complex clusters | | alphabet-greek.pdf | Full uppercase/lowercase, accented, archaic | | alphabet-devanagari.pdf | Vowels, consonants, matras, conjuncts, digits | | alphabet-turkish.pdf | 29 letters, İ/ı dotted-I distinction test | | alphabet-vietnamese.pdf | 7 base vowels × 6 tones, all diacritics | | alphabet-polish.pdf | 32 letters, digraphs, pangram | | alphabet-arabic.pdf | 28 letters, harakat, numerals, ligatures | | alphabet-hebrew.pdf | 22 letters, final forms, vowel points | | alphabet-cyrillic.pdf | 33 Russian letters, Ukrainian/Serbian extended | | alphabet-georgian.pdf | 33 Mkhedruli letters, Asomtavruli | | alphabet-armenian.pdf | 38 letters, ligatures | | alphabet-bengali.pdf | Vowels, consonants, conjuncts, digits | | alphabet-tamil.pdf | Vowels, consonants, compound characters, digits | | alphabet-hausa.pdf | Boko alphabet, hooked letters ɓ ɗ ƙ ƴ, digraphs, ʼy (v1.8.0) | | alphabet-yoruba.pdf | ẹ ọ ṣ, tone marks on ẹ / ọ, syllabic ń ǹ (v1.8.0) | | alphabet-igbo.pdf | ị ọ ụ ṅ, tone marks, digraphs (v1.8.0) | | alphabet-swahili.pdf | Plain Latin — proof that no module is required (v1.8.0) |

PDF/A Conformance Variants

| File | Content | |------|---------| | tagged-pdfa2b-default.pdf | PDF/A-2b (tagged=true, default) | | tagged-pdfa2b-explicit.pdf | PDF/A-2b (tagged='pdfa2b', explicit) | | tagged-pdfa1b.pdf | PDF/A-1b (tagged='pdfa1b', legacy) | | tagged-pdfa2u.pdf | PDF/A-2u (tagged='pdfa2u', Unicode) | | tagged-pdfa3b.pdf | PDF/A-3b (tagged='pdfa3b', embedded file attachments) |

Encrypted PDFs

| File | Content | |------|---------| | encrypted-aes128.pdf | AES-128 (V4/R4) owner-only | | encrypted-aes256.pdf | AES-256 (V5/R6) owner-only | | encrypted-aes128-user.pdf | AES-128 with user+owner passwords | | encrypted-aes256-user.pdf | AES-256 with user+owner passwords | | encrypted-readonly.pdf | AES-128 read-only (no copy/modify) | | encrypted-noprint.pdf | AES-128 fully restricted |

Sample passwords (for testing only — all documented in scripts/generate-samples.ts):

| File | Owner Password | User Password | |------|---------------|---------------| | encrypted-aes128.pdf | owner123 | (none — opens freely) | | encrypted-aes256.pdf | owner256 | (none — opens freely) | | encrypted-aes128-user.pdf | owner123 | user456 | | encrypted-aes256-user.pdf | owner256 | user789 | | encrypted-readonly.pdf | owner-ro | (none — opens freely) | | encrypted-noprint.pdf | owner-np | (none — opens freely) | | doc-encrypted-aes128.pdf | docowner | docuser | | doc-encrypted-aes256.pdf | strongowner256 | (none — opens freely) |

Document Builder Samples

| File | Content | |------|---------| | doc-headings-paragraphs.pdf | H1/H2/H3 + paragraphs with text wrapping | | doc-lists.pdf | Bullet + numbered lists | | doc-links.pdf | External hyperlink annotations | | doc-table.pdf | Embedded table in document | | doc-spacer-pagebreak.pdf | Spacers + forced page breaks (3 pages) | | doc-encrypted-aes128.pdf | Document builder + AES-128 encryption | | doc-encrypted-aes256.pdf | Document builder + AES-256 encryption | | doc-image.pdf | Image embedding (JPEG, centered) | | doc-custom-colors.pdf | Color formats (hex, tuple, PDF operator) | | doc-japanese.pdf | Japanese Unicode document (headings, lists, table) | | doc-arabic.pdf | Arabic one-page conformance document — stacked harakat, lam-alef, Persian/Urdu letters in mixed BiDi, Arabic-Indic digits (rewritten v1.8.0) | | doc-hebrew.pdf | Hebrew one-page conformance document — niqqud, dagesh, shin/sin dots, mixed LTR (rewritten v1.8.0) | | doc-thai.pdf | Thai one-page conformance document — tone marks over vowels, sara am, stacked marks (rewritten v1.8.0) | | doc-bengali.pdf | Bengali one-page conformance document — reph, ya-phala, ra-phala, ক্ষ জ্ঞ, split vowels ো ৌ, chandrabindu (rewritten v1.8.0) | | doc-tamil.pdf | Tamil one-page conformance document — ி after its consonant, ெ ே ை before, split ொ ோ ௌ, pulli, ரூ ஸ்ரீ ligatures (rewritten v1.8.0) | | doc-devanagari.pdf | Hindi one-page conformance document — ि reordering, reph, rakar, half forms, क्ष ज्ञ त्र, nukta, anusvara, digits (rewritten v1.8.0) | | doc-telugu.pdf | Telugu one-page conformance document — subjoined consonants, vattu, ై, anusvara, digits (rewritten v1.8.0) | | doc-sinhala.pdf | Sinhala one-page conformance document — kombuva, rakaransaya ශ්‍රී, yansaya, two-part vowels, hal kirima (rewritten v1.8.0) | | doc-tibetan.pdf | Tibetan one-page conformance document — consonant stacks, vowel signs, tsheg and shad (rewritten v1.8.0) | | doc-khmer.pdf | Khmer one-page conformance document — coeng subscripts, pre-base vowels, series (rewritten v1.8.0) | | doc-myanmar.pdf | Myanmar one-page conformance document — kinzi, medials, stacked consonants (rewritten v1.8.0) | | doc-amharic.pdf | Amharic one-page conformance document — syllabary orders, ። ፣ punctuation, Ethiopic digits (rewritten v1.8.0) | | doc-hausa.pdf | Hausa one-page conformance document — ɓ ɗ ƙ ƴ, capitals Ɓ Ɗ Ƙ Ƴ, ʼy, digraphs, on the latin module (v1.8.0) | | doc-yoruba.pdf | Yoruba one-page conformance document — ẹ ọ ṣ, acute and grave tone marks on ẹ / ọ, syllabic ń ǹ (v1.8.0) | | doc-igbo.pdf | Igbo one-page conformance document — ị ọ ụ ṅ with tone marks, digraphs (v1.8.0) | | doc-swahili.pdf | Swahili one-page conformance document — plain Latin, numbers and dates (v1.8.0) | | doc-lao.pdf | Lao one-page conformance document — leading vowels, tone marks over vowels, tall and descender variants, sara am, ຫຼ ໜ ໝ ligatures (v1.8.0) | | doc-taitham.pdf | Northern Thai (Tai Tham) one-page conformance document — sakot stacks, pre-base vowels, medials, tone marks, Hora digits (v1.8.0) | | doc-newtailue.pdf | Tai Lue (New Tai Lue) one-page conformance document — spacing vowels before and after, combining finals, tone letters (v1.8.0) | | doc-taile.pdf | Tai Nüa (Tai Le) one-page conformance document — spacing vowels, tone letters, finals (v1.8.0) | | doc-cham.pdf | Cham one-page conformance document — pre-base vowels, medials, finals, Cham digits (v1.8.0) | | doc-korean.pdf | Korean one-page conformance document — precomposed syllables, complex batchim, compatibility jamo, Hanja, character-level wrapping (v1.8.0) | | doc-greek.pdf | Greek one-page conformance document — tonos, dialytika, final sigma, polytonic, Greek punctuation (v1.8.0) | | doc-cyrillic.pdf | Russian one-page conformance document — ё й щ, stress marks (U+0301), Ukrainian and Serbian letters, guillemets (v1.8.0) | | doc-georgian.pdf | Georgian one-page conformance document — Mkhedruli, Mtavruli, Asomtavruli, Nuskhuri, consonant clusters (v1.8.0) | | doc-armenian.pdf | Armenian one-page conformance document — both cases, և ligature, Armenian punctuation, dram sign (v1.8.0) | | doc-turkish.pdf | Turkish one-page conformance document — İ ı, ğ ş ç ö ü, circumflex, capitalisation, lira sign (v1.8.0) | | doc-vietnamese.pdf | Vietnamese one-page conformance document — six tones, stacked diacritics, ơ ư đ, capitals with tones, dong sign (v1.8.0) | | doc-polish.pdf | Polish one-page conformance document — ogonek, kreska, ł ż, digraphs, pangram, low-high quotes (v1.8.0) | | doc-chinese-catalog.pdf | Chinese product catalog (tables, ordering info) | | doc-multi-language.pdf | Multi-language showcase: all 27 Unicode scripts in one PDF | | doc-invoice.pdf | Invoice template (line items, totals, payment link) | | doc-report-multipage.pdf | 3-page technical report (7 sections, 4 tables) | | doc-contract-bilingual.pdf | Bilingual EN/AR contract (legal sections, signatures) | | doc-showcase-all-blocks.pdf | All 13 block types in one PDF |

Compressed PDFs (FlateDecode)

| File | Content | |------|---------| | compressed-latin-100rows.pdf | 100-row Latin table (87% smaller) | | uncompressed-latin-100rows.pdf | Same 100-row table without compression (baseline) | | compressed-japanese.pdf | Japanese CIDFont + TTF subset (62% smaller) | | compressed-arabic.pdf | Arabic RTL + GSUB shaping (compressed) | | compressed-thai.pdf | Thai GSUB+GPOS shaping (compressed) | | compressed-tagged-pdfa2b.pdf | FlateDecode + Tagged PDF/A-2b (XMP uncompressed) | | compressed-encrypted-aes128.pdf | FlateDecode + AES-128 encryption | | doc-compressed.pdf | Document builder with FlateDecode |

Stress Test PDFs

| File | Content | |------|---------|
| stress-test-10k-rows.pdf | 10,000-row table (167 pages, 4.3MB) | | doc-extreme-bidi-wrapping.pdf | Extreme BiDi mixed-script text wrapping | | table-heavy-text-overflow.pdf | Dense table with heavy text overflow | | media-rich-document.pdf | Media-rich document with multiple images | | tagged-accessibility-complex.pdf | Complex tagged PDF/A accessibility tree | | layout-extreme-customization.pdf | Extreme layout customization (margins, columns, colors) |

Edge-Case Stress Tests

| File | Content | |------|---------|
| doc-unbreakable-text.pdf | 1000-char words with no spaces (DNA, URL, Base64) | | table-micro-columns.pdf | Extreme column fractions (f=0.025, mx=1) | | doc-link-annotation-bomb.pdf | 500 link annotations across 10 pages | | zero-content-empty-table.pdf | Table with headers but 0 rows | | zero-content-empty-doc.pdf | Document with no blocks | | zero-content-empty-strings.pdf | Empty headings, paragraphs, and list items | | doc-heavy-buffer-5mb.pdf | 5 MB synthetic JPEG embedded (memory stress) |

Barcode & QR Code Samples

| File | Content | |------|---------| | barcode-showcase.pdf | All 5 formats: Code 128, EAN-13, QR Code, Data Matrix, PDF417 | | barcode-alignment-sizing.pdf | Alignment (left/center/right) and custom size variations | | barcode-tagged-pdfa.pdf | Barcodes in tagged PDF/A-2b mode (/Figure structure elements) |

SVG Path Rendering Samples

| File | Content | |------|---------| | svg-basic-shapes.pdf | Rect, circle, ellipse, line, polyline, polygon | | svg-complex-paths.pdf | Cubic/quadratic Bézier curves, arcs, combined paths | | svg-tagged-pdfa.pdf | SVG elements in tagged PDF/A-2b mode |

Form Field Samples

| File | Content | |------|---------| | form-fields.pdf | All field types: text, multiline, checkbox, radio, dropdown, listbox | | form-contact.pdf | Contact form with name, email, message, and submit fields |

Digital Signature Samples

| File | Content | |------|---------| | sig-rsa-self-signed.pdf | RSA PKCS#1 v1.5 self-signed signature | | sig-ecdsa-p256.pdf | ECDSA P-256 digital signature | | sig-multi-field.pdf | PDF with multiple signature fields |

Streaming Output Samples

| File | Content | |------|---------| | streaming-document.pdf | Document streamed via buildDocumentPDFStream() | | streaming-table.pdf | Table streamed via buildPDFStream() |

PDF Parser & Modifier Samples

| File | Content | |------|---------| | parser-original.pdf | Generated → parsed → verified round-trip | | parser-modified.pdf | Generated → parsed → modified → incremental save | | parser-document.pdf | Document builder → parser round-trip verification |

Outline & Page Label Samples (v1.4.0)

| File | Content | |------|---------| | outline/outline-explicit.pdf | Nested bookmarks (/Outlines) + roman/decimal page labels | | outline/outline-auto.pdf | outline: 'auto' — bookmarks derived from headings | | outline/page-labels.pdf | Roman front matter + prefixed appendix page labels |

PDF Manipulation Samples (v1.4.0)

| File | Content | |------|---------| | manipulation/merged.pdf | mergePdfs() — multiple documents combined | | manipulation/split-report.pdf | splitPdf() — first page range | | manipulation/split-invoice.pdf | splitPdf() — second page range | | manipulation/extract-reordered.pdf | extractPages() — selected pages, reordered | | manipulation/streamed.pdf | streamToFile() — document streamed straight to disk |

API Reference

Core

| Function | Description | |----------|-------------| | buildPDF(params, layout?) | Build table-centric PDF as binary string | | buildPDFBytes(params, layout?) | Build table-centric PDF as Uint8Array | | buildDocumentPDF(params, layout?) | Build free-form document PDF as binary string | | buildDocumentPDFBytes(params, layout?) | Build free-form document PDF as Uint8Array | | wrapText(text, maxWidth, fontSize, enc) | Word-wrap text into lines | | createPDF(params, options?) | Smart dispatch (Worker or main thread) | | initNodeCompression() | Initialize native zlib for ESM (call once before compress: true) | | downloadBlob(bytes, filename) | Trigger browser download | | toBytes(str) | Convert binary string to Uint8Array | | slugify(str) | Sanitize string for filename |

Image Support

| Function | Description | |----------|-------------| | parseImage(bytes) | Auto-detect and parse JPEG or PNG | | parseJPEG(bytes) | Parse JPEG image (DCTDecode) | | parsePNG(bytes) | Parse PNG image (FlateDecode) | | detectImageFormat(bytes) | Detect JPEG or PNG from magic bytes | | buildImageXObject(img, smaskObj?) | Build PDF Image XObject dictionary | | buildImageOperators(ref, x, y, w, h) | Build q cm Do Q content stream operators |

Link Annotations

| Function | Description | |----------|-------------| | validateURL(url) | Validate URL scheme (http/https/mailto only) | | buildLinkAnnotation(annot) | Build PDF /Link annotation with /URI action | | buildInternalLinkAnnotation(link) | Build PDF /Link with /GoTo action | | isLinkAnnotation(annot) | Type guard for LinkAnnotation |

BiDi & Arabic/Hebrew Shaping

| Function | Description | |----------|-------------| | resolveBidiRuns(text) | Resolve text into BiDi runs with levels | | containsRTL(text) | Check if text contains RTL characters | | shapeArabicText(str, fontData) | Arabic GSUB positional shaping | | containsArabic(text) | Check for Arabic characters | | containsHebrew(text) | Check for Hebrew characters |

Barcode & QR Code

| Function | Description | |----------|-------------| | renderBarcode(format, data, x, y, opts?) | Unified barcode renderer (dispatches to format-specific function) | | encodeCode128(data) | Encode data into Code 128 barcode pattern (ISO 15417) | | renderCode128(data, x, y, w, h) | Render Code 128 barcode as PDF path operators | | ean13CheckDigit(digits) | Compute EAN-13 check digit (ISO 15420) | | renderEAN13(data, x, y, w, h) | Render EAN-13 barcode with guard bars and digits | | generateQR(data, ecLevel?) | Generate QR Code matrix (ISO 18004) | | renderQR(data, x, y, size, ecLevel?) | Render QR Code as PDF path operators | | generateDataMatrix(data) | Generate Data Matrix ECC 200 matrix (ISO 16022) | | renderDataMatrix(data, x, y, size) | Render Data Matrix as PDF path operators | | encodePDF417(data, ecLevel?) | Encode data into PDF417 codewords (ISO 15438) | | renderPDF417(data, x, y, w, h, ecLevel?) | Render PDF417 barcode as PDF path operators |

SVG Rendering

| Function | Description | |----------|-------------| | parseSvgPath(d) | Parse SVG path d attribute into segments | | renderSvg(segments, options?) | Render SVG segments (paths + <text>) as PDF operators |

Markup Annotations

| Function | Description | |----------|-------------| | buildAnnotation(annot, objNum) | Build a full markup annotation indirect object (v1.5.0) | | buildAnnotationBody(annot) | Build a markup annotation dictionary body (for the modifier) (v1.5.0) |

Supported MarkupAnnotation types: text, highlight, underline, strikeout, squiggly, square, circle, line, freetext.

Layout Debug & Inspection

| Function | Description | |----------|-------------| | inspectDocumentLayout(params, layout?) | Return a programmatic per-page block-geometry LayoutInspection (v1.5.0) |

Enable the visual overlay via layout: { debug: true } or a granular LayoutDebugOptions (showMargins / showContentBounds / showCells). Byte-identical when debug is off.

Font-Data Tools (pdfnative/tools)

| Function | Description | |----------|-------------| | compileFontData(buffer, opts?) | Compile a TTF/OTF Uint8Array into a font-data module source string (v1.5.0) | | parseFontData(buffer, opts?) | Parse a TTF/OTF Uint8Array into a FontDataObject (metrics, cmap, widths, glyph coverage) (v1.5.0) |

AcroForm Fields

| Function | Description | |----------|-------------| | buildFormWidget(field, objNum, pageRef) | Build form field widget annotation + appearance stream | | buildAcroFormDict(fieldRefs) | Build /AcroForm dictionary for catalog | | buildRadioGroupParent(group) | Build radio button group parent object | | buildAppearanceStreamDict(width, height) | Build appearance stream dictionary | | defaultFieldHeight(type) | Default height by field type |

Digital Signatures

| Function | Description | |----------|-------------| | buildSigDict(options) | Build /Sig dictionary with ByteRange/Contents placeholders (subFilter: 'ETSI.CAdES.detached' for PAdES, v1.7.0) | | buildDocTimeStampDict(contentsSize?) | Build a /DocTimeStamp dictionary variant (ISO 32000-2 §12.8.5, v1.7.0) | | signPdfBytes(pdf, options) | Sign a PDF with CMS/PKCS#7 detached signature (profile: 'pades', digestAlgorithm, multi-signature fieldName selector, v1.7.0) | | signPdfBytesWithTimestamp(pdf, options) | Sign + embed a verified RFC 3161 signature timestamp (PAdES B-T, v1.7.0) | | listSignatures(pdf) | Enumerate signature fields — SubFilter, ByteRange, /Contents, placeholder/timestamp flags (v1.7.0) | | collectValidationInfo(pdf, opts?) | Gather certificates + OCSP/CRL material for every signature via the injected RevocationProvider (v1.7.0) | | embedValidationInfo(pdf, data) | Write pre-collected LTV material as /DSS + /VRI — sync, offline, deterministic (v1.7.0) | | addValidationInfo(pdf, opts?) | Collect + embed in one call (PAdES B-LT, v1.7.0) | | addDocumentTimestamp(pdf, opts?) | Append a /DocTimeStamp revision (PAdES B-LTA, v1.7.0) | | estimateContentsSize(certSizes, algorithm?, opts?) | Estimate /Contents size ({ timestamp: true } adds RFC 3161 headroom, v1.7.0) | | setCryptoProvider(provider) | Install (or clear with null) a global native signature provider (v1.4.0) | | getCryptoProvider() | Return the current global CryptoProvider, or null (v1.4.0) | | setTimestampProvider(provider) / getTimestampProvider() | Global RFC 3161 transport — TimeStampReq bytes in, TimeStampResp bytes out (v1.7.0) | | setRevocationProvider(provider) / getRevocationProvider() | Global OCSP/CRL transport (v1.7.0) |

Streaming Output

| Function | Description | |----------|-------------| | buildDocumentPDFStream(params, layout?, streamOpts?) | Stream document PDF as AsyncGenerator<Uint8Array> | | buildPDFStream(params, layout?, streamOpts?) | Stream table PDF as AsyncGenerator<Uint8Array> | | buildDocumentPDFStreamTrue(params, layout?, streamOpts?) | True constant-memory document streaming — frees each part as it yields (v1.3.0) | | buildPDFStreamTrue(params, layout?, streamOpts?) | True constant-memory table streaming (v1.3.0) | | buildDocumentPDFStreamPageByPage(params, layout?) | Stream document PDF chunked at PDF object boundaries | | buildPDFStreamPageByPage(params, layout?) | Stream table PDF chunked at PDF object boundaries | | validateDocumentStreamable(params, layout?) | Validate document is compatible with streaming (no TOC, no {pages}) | | validateTableStreamable(params, layout?) | Validate table is compatible with streaming | | chunkBinaryString(str, chunkSize) | Split binary string into Uint8Array chunks | | concatChunks(chunks) | Concatenate Uint8Array chunks into one | | streamByteLength(stream) | Count total bytes from an async stream | | streamToFile(stream, filePath, opts?) | Drain an AsyncGenerator<Uint8Array> to disk with back-pressure + AbortSignal (Node) — returns { bytesWritten, path } (v1.4.0) |

Crypto (Hashing, ASN.1, RSA, ECDSA, X.509, CMS)

| Function |