modern-pdf-lib 0.9.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/LICENSE +21 -0
- package/README.md +455 -0
- package/dist/documentMerge-CNPWlWic.mjs +18351 -0
- package/dist/documentMerge-DnLzOg5P.cjs +18878 -0
- package/dist/fflateAdapter-D2mv_ttM.mjs +196 -0
- package/dist/fflateAdapter-cT4YeY_h.cjs +207 -0
- package/dist/fontSubset-BOGts8y9.mjs +203 -0
- package/dist/fontSubset-C0Rm9ih6.cjs +226 -0
- package/dist/index.cjs +4597 -0
- package/dist/index.d.cts +7898 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +7898 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +4306 -0
- package/dist/libdeflateWasm-QVHmuzw-.mjs +220 -0
- package/dist/libdeflateWasm-to2bG6NG.cjs +237 -0
- package/dist/loader-D9LTYmrX.mjs +162 -0
- package/dist/loader-mwt5wRJz.cjs +164 -0
- package/dist/pdfCatalog-DTXk0tbK.cjs +627 -0
- package/dist/pdfCatalog-Dk4qUVvx.mjs +532 -0
- package/dist/pdfPage-C9vw_D1J.cjs +5203 -0
- package/dist/pdfPage-DZA6XJzR.mjs +4544 -0
- package/dist/pngEmbed-BN-gMJrb.cjs +536 -0
- package/dist/pngEmbed-DgeNWlbS.mjs +525 -0
- package/dist/rolldown-runtime-95iHPtFO.mjs +18 -0
- package/dist/rolldown-runtime-CKhH4XqG.cjs +24 -0
- package/package.json +94 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 modern-pdf contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<br />
|
|
4
|
+
|
|
5
|
+
<picture>
|
|
6
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/badge/modern--pdf--lib-fff?style=for-the-badge&labelColor=000&color=000&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMTQgMkg2YTIgMiAwIDAgMC0yIDJ2MTZhMiAyIDAgMCAwIDIgMmgxMmEyIDIgMCAwIDAgMi0yVjhsLTYtNloiLz48cG9seWxpbmUgcG9pbnRzPSIxNCAyIDE0IDggMjAgOCIvPjxsaW5lIHgxPSIxNiIgeTE9IjEzIiB4Mj0iOCIgeTI9IjEzIi8+PGxpbmUgeDE9IjE2IiB5MT0iMTciIHgyPSI4IiB5Mj0iMTciLz48bGluZSB4MT0iMTAiIHkxPSI5IiB4Mj0iOCIgeTI9IjkiLz48L3N2Zz4" />
|
|
7
|
+
<img src="https://img.shields.io/badge/modern--pdf--lib-000?style=for-the-badge&labelColor=fff&color=fff&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMTQgMkg2YTIgMiAwIDAgMC0yIDJ2MTZhMiAyIDAgMCAwIDIgMmgxMmEyIDIgMCAwIDAgMi0yVjhsLTYtNloiLz48cG9seWxpbmUgcG9pbnRzPSIxNCAyIDE0IDggMjAgOCIvPjxsaW5lIHgxPSIxNiIgeTE9IjEzIiB4Mj0iOCIgeTI9IjEzIi8+PGxpbmUgeDE9IjE2IiB5MT0iMTciIHgyPSI4IiB5Mj0iMTciLz48bGluZSB4MT0iMTAiIHkxPSI5IiB4Mj0iOCIgeTI9IjkiLz48L3N2Zz4" alt="modern-pdf-lib" />
|
|
8
|
+
</picture>
|
|
9
|
+
|
|
10
|
+
### The PDF engine for modern JavaScript
|
|
11
|
+
|
|
12
|
+
Create, parse, fill, merge, sign, and manipulate PDF documents<br />in Node, Deno, Bun, Cloudflare Workers, and every browser.
|
|
13
|
+
|
|
14
|
+
<br />
|
|
15
|
+
|
|
16
|
+
[](https://www.npmjs.com/package/modern-pdf-lib)
|
|
17
|
+
[](https://bundlephobia.com/package/modern-pdf-lib)
|
|
18
|
+
[](#)
|
|
19
|
+
[](#)
|
|
20
|
+
[](LICENSE)
|
|
21
|
+
|
|
22
|
+
<br />
|
|
23
|
+
|
|
24
|
+
[Get Started](#quick-start) · [Features](#features) · [API](#api-surface) · [Why This?](#why-modern-pdf-lib)
|
|
25
|
+
|
|
26
|
+
<br />
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
<br />
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
npm install modern-pdf-lib
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { createPdf, PageSizes, rgb } from 'modern-pdf-lib';
|
|
42
|
+
|
|
43
|
+
const doc = createPdf();
|
|
44
|
+
const page = doc.addPage(PageSizes.A4);
|
|
45
|
+
|
|
46
|
+
page.drawText('Hello from modern-pdf-lib', {
|
|
47
|
+
x: 50,
|
|
48
|
+
y: 750,
|
|
49
|
+
size: 28,
|
|
50
|
+
color: rgb(0.13, 0.13, 0.13),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const bytes = await doc.save(); // Uint8Array
|
|
54
|
+
const stream = doc.saveAsStream(); // ReadableStream
|
|
55
|
+
const blob = await doc.saveAsBlob(); // Blob (browsers)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
<br />
|
|
59
|
+
|
|
60
|
+
## Features
|
|
61
|
+
|
|
62
|
+
<table>
|
|
63
|
+
<tr>
|
|
64
|
+
<td width="50%" valign="top">
|
|
65
|
+
|
|
66
|
+
**Create & Draw**
|
|
67
|
+
- Pages, text, images, shapes, SVG paths
|
|
68
|
+
- TrueType & OpenType font embedding
|
|
69
|
+
- Automatic font subsetting
|
|
70
|
+
- JPEG / PNG image embedding
|
|
71
|
+
- RGB, CMYK, grayscale colors
|
|
72
|
+
- Text layout (multiline, combed, auto-size)
|
|
73
|
+
|
|
74
|
+
</td>
|
|
75
|
+
<td width="50%" valign="top">
|
|
76
|
+
|
|
77
|
+
**Parse & Modify**
|
|
78
|
+
- Load existing PDFs (encrypted too)
|
|
79
|
+
- Extract text with positions
|
|
80
|
+
- Fill & flatten AcroForm fields
|
|
81
|
+
- Merge, split, copy pages
|
|
82
|
+
- Add / remove / reorder pages
|
|
83
|
+
- Incremental saves
|
|
84
|
+
|
|
85
|
+
</td>
|
|
86
|
+
</tr>
|
|
87
|
+
<tr>
|
|
88
|
+
<td width="50%" valign="top">
|
|
89
|
+
|
|
90
|
+
**Secure & Compliant**
|
|
91
|
+
- AES-256 / RC4 encryption & decryption
|
|
92
|
+
- Digital signatures (PKCS#7, timestamps)
|
|
93
|
+
- PDF/A-1b through PDF/A-3u validation
|
|
94
|
+
- Tagged PDF / PDF/UA accessibility
|
|
95
|
+
- Structure tree & marked content
|
|
96
|
+
- Redaction with content removal
|
|
97
|
+
|
|
98
|
+
</td>
|
|
99
|
+
<td width="50%" valign="top">
|
|
100
|
+
|
|
101
|
+
**Advanced**
|
|
102
|
+
- Outlines / bookmarks
|
|
103
|
+
- Optional content layers (OCGs)
|
|
104
|
+
- File attachments
|
|
105
|
+
- Watermarks
|
|
106
|
+
- Linearization (fast web view)
|
|
107
|
+
- 60+ low-level PDF operators
|
|
108
|
+
- Custom appearance providers
|
|
109
|
+
|
|
110
|
+
</td>
|
|
111
|
+
</tr>
|
|
112
|
+
</table>
|
|
113
|
+
|
|
114
|
+
<br />
|
|
115
|
+
|
|
116
|
+
## Why modern-pdf-lib?
|
|
117
|
+
|
|
118
|
+
<table>
|
|
119
|
+
<tr>
|
|
120
|
+
<th></th>
|
|
121
|
+
<th align="center"><strong>modern-pdf-lib</strong></th>
|
|
122
|
+
<th align="center">pdf-lib</th>
|
|
123
|
+
</tr>
|
|
124
|
+
|
|
125
|
+
<tr><td><strong>Runtime</strong></td>
|
|
126
|
+
<td align="center">Node, Deno, Bun, CF Workers, browsers</td>
|
|
127
|
+
<td align="center">Node, browsers</td></tr>
|
|
128
|
+
|
|
129
|
+
<tr><td><strong>Module format</strong></td>
|
|
130
|
+
<td align="center">ESM + CJS</td>
|
|
131
|
+
<td align="center">CJS (with ESM wrapper)</td></tr>
|
|
132
|
+
|
|
133
|
+
<tr><td><strong>TypeScript</strong></td>
|
|
134
|
+
<td align="center">6.0 strict</td>
|
|
135
|
+
<td align="center">3.x</td></tr>
|
|
136
|
+
|
|
137
|
+
<tr><td><strong>Parse existing PDFs</strong></td>
|
|
138
|
+
<td align="center">Yes (with decryption)</td>
|
|
139
|
+
<td align="center">Yes</td></tr>
|
|
140
|
+
|
|
141
|
+
<tr><td><strong>Text extraction</strong></td>
|
|
142
|
+
<td align="center">Yes (with positions)</td>
|
|
143
|
+
<td align="center">No</td></tr>
|
|
144
|
+
|
|
145
|
+
<tr><td><strong>Encryption</strong></td>
|
|
146
|
+
<td align="center">AES-256 + RC4</td>
|
|
147
|
+
<td align="center">No</td></tr>
|
|
148
|
+
|
|
149
|
+
<tr><td><strong>Digital signatures</strong></td>
|
|
150
|
+
<td align="center">PKCS#7, timestamps</td>
|
|
151
|
+
<td align="center">No</td></tr>
|
|
152
|
+
|
|
153
|
+
<tr><td><strong>Forms</strong></td>
|
|
154
|
+
<td align="center">Full (7 field types)</td>
|
|
155
|
+
<td align="center">Full</td></tr>
|
|
156
|
+
|
|
157
|
+
<tr><td><strong>PDF/A compliance</strong></td>
|
|
158
|
+
<td align="center">1a/1b through 3a/3b/3u</td>
|
|
159
|
+
<td align="center">No</td></tr>
|
|
160
|
+
|
|
161
|
+
<tr><td><strong>Accessibility (PDF/UA)</strong></td>
|
|
162
|
+
<td align="center">Structure tree, checker</td>
|
|
163
|
+
<td align="center">No</td></tr>
|
|
164
|
+
|
|
165
|
+
<tr><td><strong>Merge & split</strong></td>
|
|
166
|
+
<td align="center">Built-in</td>
|
|
167
|
+
<td align="center">Copy pages only</td></tr>
|
|
168
|
+
|
|
169
|
+
<tr><td><strong>Annotations</strong></td>
|
|
170
|
+
<td align="center">16 types + appearances</td>
|
|
171
|
+
<td align="center">No</td></tr>
|
|
172
|
+
|
|
173
|
+
<tr><td><strong>Streaming output</strong></td>
|
|
174
|
+
<td align="center">ReadableStream</td>
|
|
175
|
+
<td align="center">No</td></tr>
|
|
176
|
+
|
|
177
|
+
<tr><td><strong>Layers (OCG)</strong></td>
|
|
178
|
+
<td align="center">Yes</td>
|
|
179
|
+
<td align="center">No</td></tr>
|
|
180
|
+
|
|
181
|
+
<tr><td><strong>Outlines</strong></td>
|
|
182
|
+
<td align="center">Yes</td>
|
|
183
|
+
<td align="center">No</td></tr>
|
|
184
|
+
|
|
185
|
+
<tr><td><strong>Watermarks</strong></td>
|
|
186
|
+
<td align="center">Yes</td>
|
|
187
|
+
<td align="center">No</td></tr>
|
|
188
|
+
|
|
189
|
+
<tr><td><strong>Redaction</strong></td>
|
|
190
|
+
<td align="center">Yes</td>
|
|
191
|
+
<td align="center">No</td></tr>
|
|
192
|
+
|
|
193
|
+
<tr><td><strong>Linearization</strong></td>
|
|
194
|
+
<td align="center">Yes</td>
|
|
195
|
+
<td align="center">No</td></tr>
|
|
196
|
+
|
|
197
|
+
<tr><td><strong>WASM acceleration</strong></td>
|
|
198
|
+
<td align="center">Optional (compression, PNG, fonts)</td>
|
|
199
|
+
<td align="center">No</td></tr>
|
|
200
|
+
|
|
201
|
+
<tr><td><strong>Dependencies</strong></td>
|
|
202
|
+
<td align="center">1 (fflate)</td>
|
|
203
|
+
<td align="center">0</td></tr>
|
|
204
|
+
|
|
205
|
+
<tr><td><strong>Maintained</strong></td>
|
|
206
|
+
<td align="center">Active</td>
|
|
207
|
+
<td align="center">Inactive since 2021</td></tr>
|
|
208
|
+
|
|
209
|
+
</table>
|
|
210
|
+
|
|
211
|
+
<br />
|
|
212
|
+
|
|
213
|
+
## Runtimes
|
|
214
|
+
|
|
215
|
+
| Runtime | Version | Status |
|
|
216
|
+
|:---|:---|:---:|
|
|
217
|
+
| **Node.js** | 22+ | Fully supported |
|
|
218
|
+
| **Deno** | 1.40+ | Fully supported |
|
|
219
|
+
| **Bun** | 1.0+ | Fully supported |
|
|
220
|
+
| **Cloudflare Workers** | — | Fully supported |
|
|
221
|
+
| **Chrome / Edge** | 109+ | Fully supported |
|
|
222
|
+
| **Firefox** | 115+ | Fully supported |
|
|
223
|
+
| **Safari** | 16.4+ | Fully supported |
|
|
224
|
+
|
|
225
|
+
<br />
|
|
226
|
+
|
|
227
|
+
## API Surface
|
|
228
|
+
|
|
229
|
+
<details>
|
|
230
|
+
<summary><strong>Document</strong> — create, load, save, metadata</summary>
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
import { createPdf, loadPdf, PageSizes } from 'modern-pdf-lib';
|
|
234
|
+
|
|
235
|
+
// Create from scratch
|
|
236
|
+
const doc = createPdf();
|
|
237
|
+
doc.setTitle('Invoice #1042');
|
|
238
|
+
doc.setLanguage('en');
|
|
239
|
+
|
|
240
|
+
// Load existing
|
|
241
|
+
const existing = await loadPdf(pdfBytes, { password: 'secret' });
|
|
242
|
+
|
|
243
|
+
// Save
|
|
244
|
+
const bytes = await doc.save();
|
|
245
|
+
const stream = doc.saveAsStream();
|
|
246
|
+
```
|
|
247
|
+
</details>
|
|
248
|
+
|
|
249
|
+
<details>
|
|
250
|
+
<summary><strong>Pages</strong> — draw text, images, shapes, SVG</summary>
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
const page = doc.addPage(PageSizes.LETTER);
|
|
254
|
+
|
|
255
|
+
page.drawText('Hello', { x: 50, y: 700, size: 24 });
|
|
256
|
+
page.drawImage(imageRef, { x: 50, y: 400, width: 200, height: 200 });
|
|
257
|
+
page.drawRectangle({ x: 50, y: 300, width: 100, height: 50, color: rgb(0, 0.5, 1) });
|
|
258
|
+
page.drawCircle({ x: 200, y: 325, radius: 25 });
|
|
259
|
+
page.drawSvgPath('M 0 0 L 100 0 L 50 80 Z', { x: 300, y: 300 });
|
|
260
|
+
```
|
|
261
|
+
</details>
|
|
262
|
+
|
|
263
|
+
<details>
|
|
264
|
+
<summary><strong>Fonts</strong> — embed, subset, standard 14</summary>
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
// Standard fonts (no embedding needed)
|
|
268
|
+
const helvetica = doc.embedStandardFont('Helvetica');
|
|
269
|
+
|
|
270
|
+
// Custom TrueType / OpenType
|
|
271
|
+
const fontBytes = await readFile('Inter.ttf');
|
|
272
|
+
const inter = await doc.embedFont(fontBytes, { subset: true });
|
|
273
|
+
|
|
274
|
+
page.drawText('Custom font', { x: 50, y: 500, font: inter, size: 18 });
|
|
275
|
+
```
|
|
276
|
+
</details>
|
|
277
|
+
|
|
278
|
+
<details>
|
|
279
|
+
<summary><strong>Forms</strong> — fill, create, flatten</summary>
|
|
280
|
+
|
|
281
|
+
```ts
|
|
282
|
+
const form = doc.getForm();
|
|
283
|
+
|
|
284
|
+
form.getTextField('name').setText('Jane Doe');
|
|
285
|
+
form.getCheckbox('agree').check();
|
|
286
|
+
form.getDropdown('country').select('Canada');
|
|
287
|
+
|
|
288
|
+
form.flatten(); // Burn values into page content
|
|
289
|
+
```
|
|
290
|
+
</details>
|
|
291
|
+
|
|
292
|
+
<details>
|
|
293
|
+
<summary><strong>Merge & Split</strong></summary>
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
import { mergePdfs, splitPdf, copyPages } from 'modern-pdf-lib';
|
|
297
|
+
|
|
298
|
+
const merged = await mergePdfs([pdf1Bytes, pdf2Bytes]);
|
|
299
|
+
const pages = await splitPdf(pdfBytes, [
|
|
300
|
+
{ start: 0, end: 4 }, // Pages 1-5
|
|
301
|
+
{ start: 5, end: 9 }, // Pages 6-10
|
|
302
|
+
]);
|
|
303
|
+
```
|
|
304
|
+
</details>
|
|
305
|
+
|
|
306
|
+
<details>
|
|
307
|
+
<summary><strong>Encryption</strong> — AES-256, RC4, permissions</summary>
|
|
308
|
+
|
|
309
|
+
```ts
|
|
310
|
+
const bytes = await doc.save({
|
|
311
|
+
userPassword: 'reader',
|
|
312
|
+
ownerPassword: 'admin',
|
|
313
|
+
permissions: { printing: true, copying: false },
|
|
314
|
+
});
|
|
315
|
+
```
|
|
316
|
+
</details>
|
|
317
|
+
|
|
318
|
+
<details>
|
|
319
|
+
<summary><strong>Digital Signatures</strong></summary>
|
|
320
|
+
|
|
321
|
+
```ts
|
|
322
|
+
import { signPdf, verifySignatures } from 'modern-pdf-lib';
|
|
323
|
+
|
|
324
|
+
const signed = await signPdf(pdfBytes, {
|
|
325
|
+
certificate: certPem,
|
|
326
|
+
privateKey: keyPem,
|
|
327
|
+
reason: 'Approved',
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
const results = await verifySignatures(signed);
|
|
331
|
+
```
|
|
332
|
+
</details>
|
|
333
|
+
|
|
334
|
+
<details>
|
|
335
|
+
<summary><strong>Text Extraction</strong></summary>
|
|
336
|
+
|
|
337
|
+
```ts
|
|
338
|
+
import { loadPdf, extractTextWithPositions } from 'modern-pdf-lib';
|
|
339
|
+
|
|
340
|
+
const doc = await loadPdf(pdfBytes);
|
|
341
|
+
const page = doc.getPage(0);
|
|
342
|
+
const items = extractTextWithPositions(page.getOperators(), page.getResources());
|
|
343
|
+
|
|
344
|
+
for (const item of items) {
|
|
345
|
+
console.log(`"${item.text}" at (${item.x}, ${item.y})`);
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
</details>
|
|
349
|
+
|
|
350
|
+
<details>
|
|
351
|
+
<summary><strong>PDF/A & Accessibility</strong></summary>
|
|
352
|
+
|
|
353
|
+
```ts
|
|
354
|
+
import { enforcePdfA, checkAccessibility } from 'modern-pdf-lib';
|
|
355
|
+
|
|
356
|
+
// Enforce PDF/A-2b compliance
|
|
357
|
+
const archival = enforcePdfA(pdfBytes, '2b');
|
|
358
|
+
|
|
359
|
+
// Check accessibility
|
|
360
|
+
const issues = checkAccessibility(doc);
|
|
361
|
+
for (const issue of issues) {
|
|
362
|
+
console.log(`[${issue.severity}] ${issue.code}: ${issue.message}`);
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
</details>
|
|
366
|
+
|
|
367
|
+
<br />
|
|
368
|
+
|
|
369
|
+
## Install
|
|
370
|
+
|
|
371
|
+
```sh
|
|
372
|
+
# npm
|
|
373
|
+
npm install modern-pdf-lib
|
|
374
|
+
|
|
375
|
+
# pnpm
|
|
376
|
+
pnpm add modern-pdf-lib
|
|
377
|
+
|
|
378
|
+
# yarn
|
|
379
|
+
yarn add modern-pdf-lib
|
|
380
|
+
|
|
381
|
+
# bun
|
|
382
|
+
bun add modern-pdf-lib
|
|
383
|
+
|
|
384
|
+
# deno
|
|
385
|
+
import { createPdf } from 'npm:modern-pdf-lib';
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
<br />
|
|
389
|
+
|
|
390
|
+
## WASM Acceleration
|
|
391
|
+
|
|
392
|
+
All WASM modules are **optional**. Without them, identical output is produced using pure-JS fallbacks.
|
|
393
|
+
|
|
394
|
+
```ts
|
|
395
|
+
import { initWasm } from 'modern-pdf-lib';
|
|
396
|
+
|
|
397
|
+
await initWasm({
|
|
398
|
+
deflate: true, // Faster compression
|
|
399
|
+
png: true, // Faster PNG decoding
|
|
400
|
+
fonts: true, // Faster font subsetting
|
|
401
|
+
});
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
| Module | Purpose | Speedup |
|
|
405
|
+
|:---|:---|:---:|
|
|
406
|
+
| libdeflate | Stream compression | ~2x |
|
|
407
|
+
| png | PNG image decoding | ~5x |
|
|
408
|
+
| ttf | Font parsing & subsetting | ~3x |
|
|
409
|
+
| shaping | Complex script layout | ~10x |
|
|
410
|
+
|
|
411
|
+
<br />
|
|
412
|
+
|
|
413
|
+
## Project Structure
|
|
414
|
+
|
|
415
|
+
```
|
|
416
|
+
modern-pdf-lib/
|
|
417
|
+
src/
|
|
418
|
+
core/ PDF document model, objects, writer, pages
|
|
419
|
+
parser/ PDF loading, text extraction, content streams
|
|
420
|
+
form/ AcroForm fields (7 types) + appearances
|
|
421
|
+
annotation/ 16 annotation types + appearance generators
|
|
422
|
+
accessibility/ Structure tree, marked content, PDF/UA checker
|
|
423
|
+
compliance/ PDF/A validation & enforcement
|
|
424
|
+
signature/ PKCS#7 signatures, timestamps, verification
|
|
425
|
+
crypto/ AES-256, RC4, MD5, SHA-256/384/512
|
|
426
|
+
compression/ Deflate (fflate + optional WASM)
|
|
427
|
+
assets/ Font metrics/embed/subset, image embed, SVG
|
|
428
|
+
layers/ Optional content groups (OCG)
|
|
429
|
+
outline/ Bookmarks / document outline
|
|
430
|
+
metadata/ XMP metadata, viewer preferences
|
|
431
|
+
wasm/ Rust crate sources (4 modules)
|
|
432
|
+
tests/ 1,952 tests across 90 suites
|
|
433
|
+
docs/ VitePress documentation
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
<br />
|
|
437
|
+
|
|
438
|
+
## Contributing
|
|
439
|
+
|
|
440
|
+
```sh
|
|
441
|
+
git clone https://github.com/ABCrimson/modern-pdf-lib.git
|
|
442
|
+
cd modern-pdf-lib
|
|
443
|
+
npm install
|
|
444
|
+
npm test # 1,952 tests
|
|
445
|
+
npm run typecheck # TypeScript 6.0 strict
|
|
446
|
+
npm run build # ESM + CJS + declarations
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
<br />
|
|
450
|
+
|
|
451
|
+
## License
|
|
452
|
+
|
|
453
|
+
[MIT](LICENSE) © 2026
|
|
454
|
+
|
|
455
|
+
</div>
|