pdfnative 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +151 -39
- package/dist/index.cjs +4062 -776
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1107 -30
- package/dist/index.d.ts +1107 -30
- package/dist/index.js +4029 -777
- package/dist/index.js.map +1 -1
- package/dist/tools/build-emoji-font.js +1139 -0
- package/dist/worker/index.cjs +2084 -121
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.js +2084 -121
- package/dist/worker/index.js.map +1 -1
- package/fonts/noto-color-emoji-data.d.ts +28 -0
- package/fonts/noto-color-emoji-data.js +26 -0
- package/fonts/noto-ethiopic-data.d.ts +13 -0
- package/fonts/noto-ethiopic-data.js +64 -0
- package/fonts/noto-khmer-data.d.ts +13 -0
- package/fonts/noto-khmer-data.js +64 -0
- package/fonts/noto-myanmar-data.d.ts +13 -0
- package/fonts/noto-myanmar-data.js +64 -0
- package/fonts/noto-sinhala-data.d.ts +13 -0
- package/fonts/noto-sinhala-data.js +64 -0
- package/fonts/noto-telugu-data.d.ts +13 -0
- package/fonts/noto-telugu-data.js +64 -0
- package/fonts/noto-tibetan-data.d.ts +13 -0
- package/fonts/noto-tibetan-data.js +64 -0
- package/package.json +38 -7
package/README.md
CHANGED
|
@@ -12,48 +12,55 @@
|
|
|
12
12
|
[](https://pdfnative.dev)
|
|
13
13
|
[](https://www.npmjs.com/package/pdfnative-mcp)
|
|
14
14
|
[](https://www.npmjs.com/package/pdfnative-cli)
|
|
15
|
+
[](https://www.npmjs.com/package/pdfnative-react)
|
|
15
16
|
|
|
16
17
|
Pure native PDF generation library — zero vendor dependencies. ISO 32000-1 (PDF 1.7) compliant.
|
|
17
18
|
|
|
18
19
|
## Ecosystem
|
|
19
20
|
|
|
20
|
-
pdfnative ships as
|
|
21
|
+
pdfnative ships as four coordinated packages — pick whichever entry point fits your workflow:
|
|
21
22
|
|
|
22
23
|
| Package | Latest | Use it for |
|
|
23
24
|
|---|:---:|---|
|
|
24
|
-
| [`pdfnative`](https://www.npmjs.com/package/pdfnative) | **v1.
|
|
25
|
-
| [`pdfnative-cli`](https://www.npmjs.com/package/pdfnative-cli) | **
|
|
26
|
-
| [`pdfnative-mcp`](https://www.npmjs.com/package/pdfnative-mcp) | **
|
|
25
|
+
| [`pdfnative`](https://www.npmjs.com/package/pdfnative) | **v1.3.0** | The library itself — call from Node, browsers, Workers, Deno, Bun. |
|
|
26
|
+
| [`pdfnative-cli`](https://www.npmjs.com/package/pdfnative-cli) | **v1.1.0** | Render JSON → PDF, sign (RSA + ECDSA-SHA256), inspect, verify (PAdES-T + OCSP/CRL), batch, and emit JSON Schemas from the shell. Built on pdfnative 1.3.0: 22 scripts + COLRv1 emoji, `--stream-true`, `--max-blocks`, `inspect --pdfua`, and an agent-native `--json`/`E_*`/`--dry-run`/`--summary` contract. |
|
|
27
|
+
| [`pdfnative-mcp`](https://www.npmjs.com/package/pdfnative-mcp) | **v1.2.0** | Use pdfnative from Claude Desktop, Cursor, Continue, Zed (or any stdio MCP client) — **14 production tools** including `validate_pdf`, `verify_pdf`, `add_attachment`, `extract_attachments`, and `extract_text`; plus watermark support, Unicode `normalize`, token-frugal read modes (`verbosity` / `fields`), `pdfA` flags, and per-tool `_meta.apiVersion`. Built on pdfnative 1.3.0. |
|
|
28
|
+
| [`pdfnative-react`](https://www.npmjs.com/package/pdfnative-react) | **v0.2.0** | Write PDFs as declarative JSX — `<Document>`, `<Table>`, `<Barcode>`… compiled on-device to pdfnative blocks by a custom React reconciler. Render hooks (`usePdf`), client components (`PDFViewer`), and a token-frugal `DocSpec` for AI agents. |
|
|
27
29
|
|
|
28
30
|
```bash
|
|
29
31
|
npm install pdfnative # library
|
|
32
|
+
npm install pdfnative-react react # React renderer (React 19 peer)
|
|
30
33
|
npm install -g pdfnative-cli # CLI
|
|
31
34
|
npm install -g pdfnative-mcp # MCP server
|
|
32
35
|
```
|
|
33
36
|
|
|
34
|
-
Detailed docs: [CLI guide](docs/guides/cli.md) · [MCP guide](docs/guides/mcp.md) · [Onboarding cheatsheet](docs/guides/onboarding.md).
|
|
37
|
+
Detailed docs: [CLI guide](docs/guides/cli.md) · [MCP guide](docs/guides/mcp.md) · [React guide](docs/guides/react.md) · [Onboarding cheatsheet](docs/guides/onboarding.md).
|
|
35
38
|
|
|
36
39
|
## Highlights
|
|
37
40
|
|
|
38
41
|
- **Zero dependencies** — built from scratch in pure TypeScript. Zero runtime dependencies, tree-shakeable, auditable
|
|
39
42
|
- **ISO 32000-1 compliant** — valid xref tables, /Info metadata, proper font embedding
|
|
40
|
-
- **
|
|
43
|
+
- **22 Unicode scripts** — Thai, Japanese, Chinese (SC), Korean, Greek, Devanagari, Telugu, Turkish, Vietnamese, Polish, Arabic, Hebrew, Cyrillic, Georgian, Armenian, Bengali, Tamil, Sinhala, Tibetan, Khmer, Myanmar, Ethiopic
|
|
41
44
|
- **Thai OpenType shaping** — GSUB substitution + GPOS mark-to-base + mark-to-mark positioning
|
|
42
45
|
- **Arabic positional shaping** — GSUB isolated/initial/medial/final forms + lam-alef ligatures
|
|
43
|
-
- **BiDi text layout** — Unicode Bidirectional Algorithm (UAX #9) with glyph mirroring, isolates (LRI/RLI/FSI/PDI), and explicit embeddings (LRE/RLE/LRO/RLO/PDF)
|
|
44
|
-
- **USE-lite
|
|
46
|
+
- **BiDi text layout** — Unicode Bidirectional Algorithm (UAX #9) with glyph mirroring, isolates (LRI/RLI/FSI/PDI), and explicit embeddings (LRE/RLE/LRO/RLO/PDF) including character-level X4–X5 overrides (v1.3.0)
|
|
47
|
+
- **USE-lite shaping** — `classifyUseCategory` / `classifyClusters` drive joiner classification across the Devanagari, Bengali, and Tamil shapers, fixing nukta+virama, half-form, eyelash-ra, and ya-phalaa edge cases (v1.3.0)
|
|
48
|
+
- **Colour emoji (COLRv1)** — opt-in Noto Color Emoji subset; 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. [Guide →](docs/guides/colour-emoji.md)
|
|
45
49
|
- **Multi-font fallback** — automatic cross-script font switching with continuation bias
|
|
46
50
|
- **TTF subsetting** — only used glyphs embedded (dramatic file size reduction)
|
|
47
51
|
- **Tagged PDF / PDF/A** — structure tree, /ActualText, XMP metadata, sRGB OutputIntent (PDF/A-1b, 2b, 2u, 3b with embedded file attachments)
|
|
48
52
|
- **PDF Encryption** — AES-128 (V4/R4) and AES-256 (V5/R6), owner + user passwords, granular permissions
|
|
49
|
-
- **Free-form document builder** — headings, paragraphs, lists, tables, images, barcodes, SVG paths, form fields, spacers, page breaks, table of contents
|
|
50
|
-
- **Smart tables** — multi-page slicing with repeated headers, auto-wrap on column overflow, zebra striping, captions, and smart auto-fit columns (v1.2.0). [Guide →](docs/guides/tables.md)
|
|
53
|
+
- **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)
|
|
54
|
+
- **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 →](docs/guides/tables.md)
|
|
51
55
|
- **Barcode & QR code generation** — Code 128, EAN-13, QR Code, Data Matrix, PDF417 — pure PDF path operators (no images)
|
|
52
56
|
- **SVG path rendering** — path, rect, circle, ellipse, line, polyline, polygon as native PDF operators
|
|
53
57
|
- **AcroForm fields** — text, multiline, checkbox, radio, dropdown, listbox with appearance streams (ISO 32000-1 §12.7)
|
|
54
|
-
- **Digital signatures** — CMS/PKCS#7 detached signatures with RSA + ECDSA, SHA-256/384/512, X.509 parsing (ISO 32000-1 §12.8). One-call placeholder injection via `addSignaturePlaceholder()` (v1.2.0)
|
|
55
|
-
- **Streaming output** — AsyncGenerator-based progressive PDF emission with configurable chunk size,
|
|
56
|
-
- **
|
|
58
|
+
- **Digital signatures** — CMS/PKCS#7 detached signatures with RSA + ECDSA, SHA-256/384/512, 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)
|
|
59
|
+
- **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 →](docs/guides/streaming.md)
|
|
60
|
+
- **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 →](docs/guides/outlines.md)
|
|
61
|
+
- **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). [Guide →](docs/guides/viewer-preferences.md)
|
|
62
|
+
- **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 →](docs/guides/font-validation.md)
|
|
63
|
+
- **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). **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`). [Guide →](docs/guides/pdf-manipulation.md)
|
|
57
64
|
- **Image embedding** — JPEG (DCTDecode) and PNG (FlateDecode) with auto-scaling and alignment
|
|
58
65
|
- **Hyperlinks** — PDF link annotations (/URI) with URL validation, blue underlined text, tagged /Link
|
|
59
66
|
- **Header/footer templates** — configurable `PageTemplate` with left/center/right zones and `{page}`/`{pages}`/`{date}`/`{title}` placeholders
|
|
@@ -62,12 +69,13 @@ Detailed docs: [CLI guide](docs/guides/cli.md) · [MCP guide](docs/guides/mcp.md
|
|
|
62
69
|
- **FlateDecode compression** — zlib stream compression (50–90% size reduction), zero-dependency, platform-native
|
|
63
70
|
- **Web Worker support** — off-main-thread generation for large datasets
|
|
64
71
|
- **Tree-shakeable** — ESM + CJS dual build with TypeScript declarations
|
|
65
|
-
- **95%+ test coverage** —
|
|
72
|
+
- **95%+ test coverage** — 2165+ tests across 83 files, fuzz suite, dual-mode visual-regression suite, performance benchmarks
|
|
66
73
|
- **NPM provenance** — signed builds via GitHub Actions OIDC
|
|
67
74
|
- **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
|
|
68
75
|
- **No telemetry, no network calls** — verifiable in source. The library never opens a socket, fetches remote fonts, or phones home
|
|
69
|
-
- **AI client integration** — use pdfnative from Claude Desktop, Cursor, Continue, and Zed via [`pdfnative-mcp`](https://github.com/Nizoka/pdfnative-mcp)
|
|
70
|
-
- **Command-line interface** — render, sign,
|
|
76
|
+
- **AI client integration** — use pdfnative from Claude Desktop, Cursor, Continue, and Zed via [`pdfnative-mcp`](https://github.com/Nizoka/pdfnative-mcp) — **14 production tools** (generate, tables, barcodes, forms, sign, verify, validate, attachments, extraction, inspect)
|
|
77
|
+
- **Command-line interface** — render, sign, verify, inspect, and batch-render PDFs from the shell with [`pdfnative-cli`](https://github.com/Nizoka/pdfnative-cli) — zero-config, scriptable, agent-native (`--json`/`E_*`/`--dry-run`), ideal for CI/CD pipelines
|
|
78
|
+
- **React renderer** — author PDFs as declarative JSX with [`pdfnative-react`](https://github.com/Nizoka/pdfnative-react): `<Document>`/`<Table>`/`<Barcode>` components, `usePdf`/`PDFViewer` client hooks, on-device rendering with no DOM or headless browser
|
|
71
79
|
|
|
72
80
|
## Installation
|
|
73
81
|
|
|
@@ -85,8 +93,8 @@ npm install pdfnative
|
|
|
85
93
|
- ♿ **Accessibility:** [docs/guides/accessibility.md](docs/guides/accessibility.md) — tagged PDF, PDF/UA, PDF/A.
|
|
86
94
|
- ❓ **FAQ:** [docs/guides/faq.md](docs/guides/faq.md) — fonts, encryption, signatures, comparisons.
|
|
87
95
|
- 🛠️ **Troubleshooting:** [docs/guides/troubleshooting.md](docs/guides/troubleshooting.md) — common pitfalls.
|
|
88
|
-
- 🎮 **Playgrounds:** [docs/playgrounds/extreme-scripts.html](docs/playgrounds/extreme-scripts.html) (live BiDi/Indic stress tests)
|
|
89
|
-
- 🧪 **Sample PDFs:** [scripts/generators/](scripts/generators/) — ~
|
|
96
|
+
- 🎮 **Playgrounds:** [docs/playgrounds/extreme-scripts.html](docs/playgrounds/extreme-scripts.html) (live BiDi/Indic stress tests), [docs/playgrounds/medical-800.html](docs/playgrounds/medical-800.html) (800-page Web Worker showcase), and [docs/playgrounds/toolkit.html](docs/playgrounds/toolkit.html) (v1.4.0 bookmarks, page labels, viewer prefs, nested lists, cell borders, merge/split/extract).
|
|
97
|
+
- 🧪 **Sample PDFs:** [scripts/generators/](scripts/generators/) — ~201 sample PDFs across 36 categories (see [Sample PDFs](#sample-pdfs) below).
|
|
90
98
|
|
|
91
99
|
## Why pdfnative?
|
|
92
100
|
|
|
@@ -201,6 +209,12 @@ registerFonts({
|
|
|
201
209
|
hy: () => import('pdfnative/fonts/noto-armenian-data.js'),
|
|
202
210
|
bn: () => import('pdfnative/fonts/noto-bengali-data.js'),
|
|
203
211
|
ta: () => import('pdfnative/fonts/noto-tamil-data.js'),
|
|
212
|
+
te: () => import('pdfnative/fonts/noto-telugu-data.js'), // v1.3.0
|
|
213
|
+
si: () => import('pdfnative/fonts/noto-sinhala-data.js'), // v1.3.0
|
|
214
|
+
bo: () => import('pdfnative/fonts/noto-tibetan-data.js'), // v1.3.0
|
|
215
|
+
km: () => import('pdfnative/fonts/noto-khmer-data.js'), // v1.3.0
|
|
216
|
+
my: () => import('pdfnative/fonts/noto-myanmar-data.js'), // v1.3.0
|
|
217
|
+
am: () => import('pdfnative/fonts/noto-ethiopic-data.js'), // v1.3.0
|
|
204
218
|
// v1.1.0+ — optional Latin fallback for PDF/A documents with curly quotes,
|
|
205
219
|
// em-dash, ellipsis, etc. (activates automatically when needed):
|
|
206
220
|
latin: () => import('pdfnative/fonts/noto-sans-data.js'),
|
|
@@ -386,6 +400,28 @@ npx pdfnative-build-font fonts/ttf/MyFont.ttf fonts/my-font-data.js
|
|
|
386
400
|
|
|
387
401
|
The tool extracts cmap, widths, metrics, GSUB, GPOS, and embeds the raw TTF as base64.
|
|
388
402
|
|
|
403
|
+
### Full colour-emoji coverage (`pdfnative-build-emoji-font`)
|
|
404
|
+
|
|
405
|
+
The bundled colour-emoji module (`pdfnative/fonts/noto-color-emoji-data.js`)
|
|
406
|
+
ships a lean curated subset to keep the package small. When you need glyphs
|
|
407
|
+
beyond that subset — up to the **full ~3,600-glyph** Noto Color Emoji set — a
|
|
408
|
+
second bundled binary generates a custom data module on demand, so even
|
|
409
|
+
**pdfnative-only** users get full coverage without the package ever carrying the
|
|
410
|
+
~32 MB source font:
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
# Download the pinned Noto Color Emoji (SHA-256 verified) and emit every glyph
|
|
414
|
+
npx pdfnative-build-emoji-font --download --all --out my-color-emoji-data.js
|
|
415
|
+
|
|
416
|
+
# …or build from a local TTF, selecting only the glyphs you need
|
|
417
|
+
npx pdfnative-build-emoji-font --ttf NotoColorEmoji-Regular.ttf \
|
|
418
|
+
--codepoints "1F600,1F680,2764" --out my-color-emoji-data.js
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
Select glyphs with `--all`, `--preset`, `--codepoints`, or `--ranges`, then
|
|
422
|
+
register the generated module under lang `'emoji'`. See the
|
|
423
|
+
[Colour-emoji CLI guide](docs/guides/colour-emoji-cli.md).
|
|
424
|
+
|
|
389
425
|
## Visual PDF Inspection
|
|
390
426
|
|
|
391
427
|
<a id="sample-pdfs"></a>
|
|
@@ -420,7 +456,7 @@ See [scripts/README.md](scripts/README.md) for the modular generator architectur
|
|
|
420
456
|
| `sample-hy.pdf` | Armenian |
|
|
421
457
|
| `sample-bn.pdf` | Bengali (GSUB conjuncts + GPOS marks) |
|
|
422
458
|
| `sample-ta.pdf` | Tamil (GSUB + split vowel decomposition) |
|
|
423
|
-
| `sample-multi.pdf` | Mixed: all
|
|
459
|
+
| `sample-multi.pdf` | Mixed: all 22 scripts in one PDF |
|
|
424
460
|
| `sample-pagination.pdf` | 200 rows, multi-page layout |
|
|
425
461
|
|
|
426
462
|
### Diverse Use Cases (non-financial)
|
|
@@ -515,8 +551,14 @@ See [scripts/README.md](scripts/README.md) for the modular generator architectur
|
|
|
515
551
|
| `doc-bengali.pdf` | Bengali document (GSUB conjuncts + GPOS marks) |
|
|
516
552
|
| `doc-tamil.pdf` | Tamil document (GSUB substitution + split vowels) |
|
|
517
553
|
| `doc-devanagari.pdf` | Hindi (Devanagari) document — GSUB conjuncts, reph reordering, matra reordering, split vowels |
|
|
554
|
+
| `doc-telugu.pdf` | Telugu document (virama conjuncts + GPOS marks, no reph) |
|
|
555
|
+
| `doc-sinhala.pdf` | Sinhala document (virama conjuncts + pre-base kombuva reordering) |
|
|
556
|
+
| `doc-tibetan.pdf` | Tibetan document (vertical subjoined-consonant stacking) |
|
|
557
|
+
| `doc-khmer.pdf` | Khmer document (USE-lite: coeng subscripts, pre-base vowels) |
|
|
558
|
+
| `doc-myanmar.pdf` | Myanmar document (USE-lite: medials, pre-base reordering) |
|
|
559
|
+
| `doc-amharic.pdf` | Amharic/Ethiopic document (syllabic abugida, no reordering) |
|
|
518
560
|
| `doc-chinese-catalog.pdf` | Chinese product catalog (tables, ordering info) |
|
|
519
|
-
| `doc-multi-language.pdf` | Multi-language:
|
|
561
|
+
| `doc-multi-language.pdf` | Multi-language showcase: all 22 Unicode scripts in one PDF |
|
|
520
562
|
| `doc-invoice.pdf` | Invoice template (line items, totals, payment link) |
|
|
521
563
|
| `doc-report-multipage.pdf` | 3-page technical report (7 sections, 4 tables) |
|
|
522
564
|
| `doc-contract-bilingual.pdf` | Bilingual EN/AR contract (legal sections, signatures) |
|
|
@@ -604,6 +646,24 @@ See [scripts/README.md](scripts/README.md) for the modular generator architectur
|
|
|
604
646
|
| `parser-modified.pdf` | Generated → parsed → modified → incremental save |
|
|
605
647
|
| `parser-document.pdf` | Document builder → parser round-trip verification |
|
|
606
648
|
|
|
649
|
+
### Outline & Page Label Samples (v1.4.0)
|
|
650
|
+
|
|
651
|
+
| File | Content |
|
|
652
|
+
|------|---------|
|
|
653
|
+
| `outline/outline-explicit.pdf` | Nested bookmarks (`/Outlines`) + roman/decimal page labels |
|
|
654
|
+
| `outline/outline-auto.pdf` | `outline: 'auto'` — bookmarks derived from headings |
|
|
655
|
+
| `outline/page-labels.pdf` | Roman front matter + prefixed appendix page labels |
|
|
656
|
+
|
|
657
|
+
### PDF Manipulation Samples (v1.4.0)
|
|
658
|
+
|
|
659
|
+
| File | Content |
|
|
660
|
+
|------|---------|
|
|
661
|
+
| `manipulation/merged.pdf` | `mergePdfs()` — multiple documents combined |
|
|
662
|
+
| `manipulation/split-report.pdf` | `splitPdf()` — first page range |
|
|
663
|
+
| `manipulation/split-invoice.pdf` | `splitPdf()` — second page range |
|
|
664
|
+
| `manipulation/extract-reordered.pdf` | `extractPages()` — selected pages, reordered |
|
|
665
|
+
| `manipulation/streamed.pdf` | `streamToFile()` — document streamed straight to disk |
|
|
666
|
+
|
|
607
667
|
## API Reference
|
|
608
668
|
|
|
609
669
|
### Core
|
|
@@ -691,6 +751,8 @@ See [scripts/README.md](scripts/README.md) for the modular generator architectur
|
|
|
691
751
|
| `buildSigDict(options)` | Build `/Sig` dictionary with ByteRange/Contents placeholders |
|
|
692
752
|
| `signPdfBytes(pdf, options)` | Sign a PDF with CMS/PKCS#7 detached signature |
|
|
693
753
|
| `estimateContentsSize(options)` | Estimate hex-encoded `/Contents` size for pre-allocation |
|
|
754
|
+
| `setCryptoProvider(provider)` | Install (or clear with `null`) a global native signature provider (v1.4.0) |
|
|
755
|
+
| `getCryptoProvider()` | Return the current global `CryptoProvider`, or `null` (v1.4.0) |
|
|
694
756
|
|
|
695
757
|
### Streaming Output
|
|
696
758
|
|
|
@@ -698,11 +760,16 @@ See [scripts/README.md](scripts/README.md) for the modular generator architectur
|
|
|
698
760
|
|----------|-------------|
|
|
699
761
|
| `buildDocumentPDFStream(params, layout?, streamOpts?)` | Stream document PDF as `AsyncGenerator<Uint8Array>` |
|
|
700
762
|
| `buildPDFStream(params, layout?, streamOpts?)` | Stream table PDF as `AsyncGenerator<Uint8Array>` |
|
|
763
|
+
| `buildDocumentPDFStreamTrue(params, layout?, streamOpts?)` | **True constant-memory** document streaming — frees each part as it yields (v1.3.0) |
|
|
764
|
+
| `buildPDFStreamTrue(params, layout?, streamOpts?)` | **True constant-memory** table streaming (v1.3.0) |
|
|
765
|
+
| `buildDocumentPDFStreamPageByPage(params, layout?)` | Stream document PDF chunked at PDF object boundaries |
|
|
766
|
+
| `buildPDFStreamPageByPage(params, layout?)` | Stream table PDF chunked at PDF object boundaries |
|
|
701
767
|
| `validateDocumentStreamable(params, layout?)` | Validate document is compatible with streaming (no TOC, no `{pages}`) |
|
|
702
768
|
| `validateTableStreamable(params, layout?)` | Validate table is compatible with streaming |
|
|
703
769
|
| `chunkBinaryString(str, chunkSize)` | Split binary string into `Uint8Array` chunks |
|
|
704
770
|
| `concatChunks(chunks)` | Concatenate `Uint8Array` chunks into one |
|
|
705
771
|
| `streamByteLength(stream)` | Count total bytes from an async stream |
|
|
772
|
+
| `streamToFile(stream, filePath, opts?)` | Drain an `AsyncGenerator<Uint8Array>` to disk with back-pressure + `AbortSignal` (Node) — returns `{ bytesWritten, chunks }` (v1.4.0) |
|
|
706
773
|
|
|
707
774
|
### Crypto (Hashing, ASN.1, RSA, ECDSA, X.509, CMS)
|
|
708
775
|
|
|
@@ -731,6 +798,10 @@ See [scripts/README.md](scripts/README.md) for the modular generator architectur
|
|
|
731
798
|
| `isRef(v)` / `isDict(v)` / `isArray(v)` / `isStream(v)` | Type guards for parsed PDF values |
|
|
732
799
|
| `dictGet(dict, key)` / `dictGetName(dict, key)` | Dictionary value accessors |
|
|
733
800
|
| `inflateSync(data)` | Decompress FlateDecode data (zlib inflate) |
|
|
801
|
+
| `validatePdfUA(bytes)` | Read-only PDF/UA structural checker — returns `{ valid, errors, warnings }` (v1.3.0) |
|
|
802
|
+
| `mergePdfs(sources, opts?)` | Merge multiple PDFs into one, rebuilding a clean object graph; `opts.maxOutputSize` caps output at 256 MiB by default (v1.4.0) |
|
|
803
|
+
| `splitPdf(src, ranges, opts?)` | Split a PDF into multiple documents by inclusive 0-based page ranges (v1.4.0) |
|
|
804
|
+
| `extractPages(src, indices, opts?)` | Extract specific pages (0-based) into a new PDF (v1.4.0) |
|
|
734
805
|
|
|
735
806
|
### Document Block Types
|
|
736
807
|
|
|
@@ -739,7 +810,7 @@ See [scripts/README.md](scripts/README.md) for the modular generator architectur
|
|
|
739
810
|
| `HeadingBlock` | H1/H2/H3 with color, auto-wrapped |
|
|
740
811
|
| `ParagraphBlock` | Text with fontSize, lineHeight, align, indent, color |
|
|
741
812
|
| `TableBlock` | Headers + rows using PdfRow/ColumnDef |
|
|
742
|
-
| `ListBlock` | Bullet or numbered items |
|
|
813
|
+
| `ListBlock` | Bullet or numbered items; entries may be plain strings or nested `ListItem` `{ text, items }` for hierarchical lists (v1.4.0) |
|
|
743
814
|
| `ImageBlock` | JPEG/PNG with optional width, height, align, alt text |
|
|
744
815
|
| `LinkBlock` | Hyperlink with URL, blue underline, tagged /Link |
|
|
745
816
|
| `SpacerBlock` | Vertical whitespace |
|
|
@@ -802,6 +873,7 @@ const pdf = buildPDFBytes(params, { compress: true });
|
|
|
802
873
|
| `hasFontLoader(lang)` | Check if loader is registered |
|
|
803
874
|
| `getRegisteredLangs()` | List registered language codes |
|
|
804
875
|
| `createEncodingContext(fontEntries)` | Create encoding context |
|
|
876
|
+
| `validateFontData(data)` | Opt-in structural validation of custom font data — returns `{ valid, errors, warnings }` (v1.4.0) |
|
|
805
877
|
|
|
806
878
|
### Shaping
|
|
807
879
|
|
|
@@ -811,6 +883,11 @@ const pdf = buildPDFBytes(params, { compress: true });
|
|
|
811
883
|
| `shapeBengaliText(str, fontData)` | Bengali GSUB conjuncts + GPOS marks |
|
|
812
884
|
| `shapeTamilText(str, fontData)` | Tamil GSUB + split vowel decomposition |
|
|
813
885
|
| `shapeDevanagariText(str, fontData)` | Devanagari cluster shaping + GSUB/GPOS |
|
|
886
|
+
| `shapeTeluguText(str, fontData)` | Telugu GSUB conjuncts + GPOS marks (v1.3.0) |
|
|
887
|
+
| `shapeSinhalaText(str, fontData)` | Sinhala conjuncts + pre-base reorder + GSUB/GPOS (v1.3.0) |
|
|
888
|
+
| `shapeTibetanText(str, fontData)` | Tibetan vertical subjoined stacking (v1.3.0) |
|
|
889
|
+
| `shapeKhmerText(str, fontData)` | Khmer USE-lite — coeng subscripts + pre-base vowels (v1.3.0) |
|
|
890
|
+
| `shapeMyanmarText(str, fontData)` | Myanmar USE-lite — medials + virama stacking (v1.3.0) |
|
|
814
891
|
| `detectFallbackLangs(texts, primaryLang)` | Detect needed fallback fonts |
|
|
815
892
|
| `detectCharLang(codePoint)` | Map codepoint to preferred font language |
|
|
816
893
|
| `splitTextByFont(str, fontEntries)` | Multi-font text run splitting |
|
|
@@ -821,6 +898,10 @@ const pdf = buildPDFBytes(params, { compress: true });
|
|
|
821
898
|
| `shapeArabicText(str, fontData)` | Arabic GSUB positional shaping |
|
|
822
899
|
| `containsArabic(text)` | Detect Arabic content |
|
|
823
900
|
| `containsHebrew(text)` | Detect Hebrew content |
|
|
901
|
+
| `containsTelugu(text)` | Detect Telugu content (v1.3.0) |
|
|
902
|
+
| `isTeluguCodepoint(cp)` | Telugu codepoint predicate (v1.3.0) |
|
|
903
|
+
| `containsSinhala(text)` / `containsTibetan(text)` / `containsKhmer(text)` / `containsMyanmar(text)` / `containsEthiopic(text)` | Detect script content (v1.3.0) |
|
|
904
|
+
| `isSinhalaCodepoint(cp)` / `isTibetanCodepoint(cp)` / `isKhmerCodepoint(cp)` / `isMyanmarCodepoint(cp)` / `isEthiopicCodepoint(cp)` | Codepoint predicates (v1.3.0) |
|
|
824
905
|
|
|
825
906
|
### Layout Constants
|
|
826
907
|
|
|
@@ -837,15 +918,13 @@ const pdf = buildPDFBytes(params, { compress: true });
|
|
|
837
918
|
|
|
838
919
|
## Ecosystem
|
|
839
920
|
|
|
840
|
-
pdfnative ships as a library, but
|
|
921
|
+
pdfnative ships as a library, but three official companion packages cover the most common non-library use cases — a CLI, an MCP server, and a React renderer. All live in separate repositories and depend on `pdfnative` only through the public API, so the core library stays zero-dependency.
|
|
841
922
|
|
|
842
923
|
### pdfnative-cli — command-line interface
|
|
843
924
|
|
|
844
|
-
[`pdfnative-cli`](https://github.com/Nizoka/pdfnative-cli)
|
|
845
|
-
|
|
846
|
-
**New in v0.3.0:** ECDSA-SHA256 (P-256) signing fully wired, real CMS/PKCS#7 verification with RFC 3161 timestamp detection, automatic signature-placeholder injection on `sign`, plus three iteration-friendly `render` flags (`--watch`, `--template`, `--font {latin,emoji}`). **100 % backward-compatible** with v0.2.0.
|
|
925
|
+
[`pdfnative-cli`](https://github.com/Nizoka/pdfnative-cli) v1.1.0 is the **official CLI**, built on `pdfnative` v1.3.0. It exposes six commands — `render`, `sign`, `inspect`, `verify`, `batch`, and `schema` (plus `completion`) — for use in shell scripts, Makefiles, GitHub Actions, and Docker images. Zero extra runtime dependencies, npm-provenance-signed, with a CycloneDX SBOM attached to every release.
|
|
847
926
|
|
|
848
|
-
**
|
|
927
|
+
**New in v1.1.0:** **22 Unicode scripts + COLRv1 colour emoji** through the `--font`/`--lang` shortcuts, **true constant-memory streaming** (`--stream-true`), a `--max-blocks` cap for very large documents, and a **PDF/UA (ISO 14289-1) structural validator** (`inspect --pdfua` / `--check pdfua`). It also adds an **agent-native contract** — a global `--json` status/error envelope, stable `E_*` error codes, a `--dry-run` validation mode, the new **`schema`** command (Draft 2020-12), and token-economy output projection (`--summary` / `--fields` + compact JSON) that cuts agent output ~90 %. **100 % backward-compatible.**
|
|
849
928
|
|
|
850
929
|
```bash
|
|
851
930
|
# render with full layout coverage (encryption + watermark + PDF/A-2b)
|
|
@@ -859,21 +938,25 @@ npx pdfnative-cli sign --input report.pdf --output signed.pdf \
|
|
|
859
938
|
--signing-time 2026-04-28T10:00:00Z \
|
|
860
939
|
--cert-chain intermediate.pem
|
|
861
940
|
|
|
862
|
-
# verify embedded signatures (byte-range + chain + trust)
|
|
941
|
+
# verify embedded signatures (byte-range + chain + trust + revocation)
|
|
863
942
|
npx pdfnative-cli verify --input signed.pdf --strict --trust ca-root.pem
|
|
864
943
|
|
|
865
|
-
# inspect with CI assertions (exit 1 on failure)
|
|
944
|
+
# inspect with CI assertions, incl. PDF/UA accessibility gate (exit 1 on failure)
|
|
866
945
|
npx pdfnative-cli inspect --input signed.pdf \
|
|
867
|
-
--check pdfa --check signed --
|
|
946
|
+
--check pdfa --check signed --check pdfua --json --summary
|
|
868
947
|
```
|
|
869
948
|
|
|
870
|
-
See the [CLI Guide](https://pdfnative.dev/guides/cli.html) for the full
|
|
949
|
+
See the [CLI Guide](https://pdfnative.dev/guides/cli.html) for the full v1.1.0 reference, agent contract, security model, and recipes. Try the [interactive CLI playground](https://pdfnative.dev/playgrounds/cli.html) to build commands without leaving the browser.
|
|
871
950
|
|
|
872
951
|
### pdfnative-mcp — Model Context Protocol server
|
|
873
952
|
|
|
874
|
-
[`pdfnative-mcp`](https://github.com/Nizoka/pdfnative-mcp)
|
|
953
|
+
[`pdfnative-mcp`](https://github.com/Nizoka/pdfnative-mcp) v1.2.0 is a **Model Context Protocol server** that bridges pdfnative to any MCP-compatible AI client. Once configured, your AI assistant can generate PDFs, embed barcodes, create forms, sign and verify documents, validate PDF/UA structure, embed and extract attachments, extract text, render international text, and inspect existing PDFs — all without writing code.
|
|
875
954
|
|
|
876
|
-
**
|
|
955
|
+
**v1.0.0:** first stable MCP release with 12 tools, `verify_pdf`, `add_attachment` (Factur-X / ZUGFeRD PDF/A-3), `extract_text`, smart-table options, auto-placeholder signing, and `_meta.apiVersion`.
|
|
956
|
+
|
|
957
|
+
**v1.1.0:** adds `validate_pdf`, six additional scripts (Telugu, Sinhala, Tibetan, Khmer, Myanmar, Ethiopic), and COLRv1 colour-emoji support via the pdfnative 1.3.0 engine.
|
|
958
|
+
|
|
959
|
+
**v1.2.0:** adds `extract_attachments`, watermark options on document tools, Unicode `normalize` (NFC/NFD/NFKC/NFKD), token-frugal read modes (`verbosity`/`fields`), and returns base64 PDF bytes once via a `resource` block.
|
|
877
960
|
|
|
878
961
|
```bash
|
|
879
962
|
npx -y pdfnative-mcp
|
|
@@ -884,14 +967,19 @@ npx -y pdfnative-mcp
|
|
|
884
967
|
| Tool | Purpose |
|
|
885
968
|
|------|---------|
|
|
886
969
|
| `generate_basic_pdf` | Multi-page documents from structured blocks (headings, paragraphs, lists) |
|
|
887
|
-
| `add_table` |
|
|
970
|
+
| `add_table` | Smart tables (`wrap`, `repeatHeader`, `zebra`, `caption`, `minRowHeight`, `cellPadding`) |
|
|
888
971
|
| `add_barcode` | QR Code, Code 128, EAN-13, Data Matrix, PDF417 |
|
|
889
|
-
| `add_international_text` |
|
|
972
|
+
| `add_international_text` | 24 script/font codes (22 Unicode scripts + `latin` + `emoji`) with BiDi & OpenType shaping |
|
|
890
973
|
| `add_form` | Interactive AcroForm PDFs (text, checkbox, radio, dropdown) |
|
|
891
974
|
| `embed_image` | Embed a JPEG or PNG image (base64) |
|
|
892
975
|
| `prepare_signature_placeholder` | PDF with a `/Sig` field ready to be signed |
|
|
893
976
|
| `sign_pdf` | CMS/PKCS#7 digital signatures (RSA-SHA256 / ECDSA-SHA256) |
|
|
894
|
-
| `
|
|
977
|
+
| `validate_pdf` | **v1.1.0** — read-only PDF/UA structural validation |
|
|
978
|
+
| `verify_pdf` | **v1.0.0** — verify every PAdES signature (integrity + value + optional chain trust) |
|
|
979
|
+
| `add_attachment` | **v1.0.0** — PDF/A-3 with embedded files (Factur-X / ZUGFeRD) |
|
|
980
|
+
| `extract_attachments` | **v1.2.0** — extract embedded files (optionally metadata-only) |
|
|
981
|
+
| `extract_text` | **v1.0.0** — best-effort plain-text extraction from a non-encrypted PDF |
|
|
982
|
+
| `inspect_pdf` | Structured PDF report (metadata, pages, signatures, PDF/A, attachments, placeholder state) |
|
|
895
983
|
|
|
896
984
|
### Claude Desktop configuration
|
|
897
985
|
|
|
@@ -902,7 +990,7 @@ npx -y pdfnative-mcp
|
|
|
902
990
|
"command": "npx",
|
|
903
991
|
"args": ["-y", "pdfnative-mcp"],
|
|
904
992
|
"env": {
|
|
905
|
-
"
|
|
993
|
+
"PDFNATIVE_MCP_OUTPUT_DIR": "/Users/you/Documents/mcp-pdfs"
|
|
906
994
|
}
|
|
907
995
|
}
|
|
908
996
|
}
|
|
@@ -911,6 +999,30 @@ npx -y pdfnative-mcp
|
|
|
911
999
|
|
|
912
1000
|
See the [MCP Integration Guide](https://pdfnative.dev/guides/mcp.html) and the [pdfnative-mcp repository](https://github.com/Nizoka/pdfnative-mcp) for configuration on Cursor, Continue, Zed, and more.
|
|
913
1001
|
|
|
1002
|
+
### pdfnative-react — declarative JSX renderer
|
|
1003
|
+
|
|
1004
|
+
[`pdfnative-react`](https://github.com/Nizoka/pdfnative-react) v0.2.0 turns declarative **JSX** into real, on-device PDFs powered by the zero-dependency pdfnative engine — no DOM, no headless browser, no SaaS round-trips. A custom React reconciler compiles your component tree synchronously into the pdfnative block model. Requires **React 19** and **Node.js ≥ 20** (React is a peer dependency; pdfnative itself stays zero-dependency).
|
|
1005
|
+
|
|
1006
|
+
```tsx
|
|
1007
|
+
import { Document, Heading, Text, Table, renderToBytes } from 'pdfnative-react';
|
|
1008
|
+
|
|
1009
|
+
const bytes = renderToBytes(
|
|
1010
|
+
<Document title="Invoice #1024" footerText="Acme Inc">
|
|
1011
|
+
<Heading level={1}>Invoice #1024</Heading>
|
|
1012
|
+
<Text>Thank you for your business.</Text>
|
|
1013
|
+
<Table
|
|
1014
|
+
headers={['Item', 'Qty', 'Total']}
|
|
1015
|
+
rows={[{ cells: ['Pro plan', '1', '$49.00'], type: 'default', pointed: false }]}
|
|
1016
|
+
zebra
|
|
1017
|
+
/>
|
|
1018
|
+
</Document>,
|
|
1019
|
+
); // → Uint8Array, a valid PDF
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
Every component (`Document`, `Page`, `Heading`, `Paragraph`/`Text`, `List`/`Item`, `Table`/`Row`/`Cell`, `Image`, `Link`, `Spacer`, `PageBreak`, `TableOfContents`, `Barcode`, `Svg`, `FormField`) maps 1:1 onto a pdfnative block. Render with `renderToBytes` / `renderToBlob` / `renderToStream` / `renderToFile`, preview live with the `usePdf` hook and `PDFViewer` / `PDFDownloadLink` / `BlobProvider` client components, or let AI agents author documents with the token-frugal `DocSpec` (terse JSON tuples that compile to the *same* PDF, validated by a versioned JSON Schema).
|
|
1023
|
+
|
|
1024
|
+
See the [React Guide](https://pdfnative.dev/guides/react.html) for the full component reference, and try the [interactive React playground](https://pdfnative.dev/playgrounds/react.html) to render JSX to PDF in your browser.
|
|
1025
|
+
|
|
914
1026
|
## Architecture
|
|
915
1027
|
|
|
916
1028
|
```
|
|
@@ -971,9 +1083,9 @@ src/
|
|
|
971
1083
|
├── worker-api.ts # Worker/main-thread dispatch
|
|
972
1084
|
└── pdf-worker.ts # Self-contained worker entry
|
|
973
1085
|
|
|
974
|
-
fonts/ # Pre-built font data modules (
|
|
1086
|
+
fonts/ # Pre-built font data modules (22 scripts)
|
|
975
1087
|
tools/ # CLI: build-font-data.cjs (TTF → JS module)
|
|
976
|
-
scripts/ # Modular sample PDF generation (
|
|
1088
|
+
scripts/ # Modular sample PDF generation (36 generators, 201+ PDFs)
|
|
977
1089
|
tests/ # 1726+ tests (48 files: unit + integration + fuzz + parser)
|
|
978
1090
|
bench/ # Performance benchmarks (vitest bench)
|
|
979
1091
|
```
|
|
@@ -1191,7 +1303,7 @@ pdfnative targets ES2020 and works in any environment that supports `Uint8Array`
|
|
|
1191
1303
|
|
|
1192
1304
|
## Origin
|
|
1193
1305
|
|
|
1194
|
-
pdfnative was born inside [**plika.app**](https://plika.app) — a personal finance application where high-quality, multi-language PDF generation (bank statements, transaction reports) was a core requirement. Rather than depending on heavy third-party libraries, the PDF engine was built from scratch with zero dependencies, strict ISO compliance, and native support for
|
|
1306
|
+
pdfnative was born inside [**plika.app**](https://plika.app) — a personal finance application where high-quality, multi-language PDF generation (bank statements, transaction reports) was a core requirement. Rather than depending on heavy third-party libraries, the PDF engine was built from scratch with zero dependencies, strict ISO compliance, and native support for 22 Unicode scripts.
|
|
1195
1307
|
|
|
1196
1308
|
The decision was then made to extract the engine into an independent open-source library so that everyone can benefit from production-grade PDF generation — not just plika.app users.
|
|
1197
1309
|
|