@jackgreen2018/pdf-engine-wasm
v1.0.6
Published
A lightweight, high-performance PDF processing library that runs in the browser and Node.js via Rust/WASM. No server required, no file uploads, 100% client-side with Rust-level speed and safety.
Maintainers
Readme
Scope: full engine (see SCOPE.md).
pdf-engine-wasm — Rust/WASM PDF Processing Library
A high-performance PDF processing library for Node.js and the browser. Built with Rust + WebAssembly. Zero server, zero dependencies on the user side, 2× faster than pdf-lib on page count, 4× faster on merge (see benchmark).
Features
- Page Count: Quickly determine the number of pages in a PDF using a proper PDF parser
- Text Extraction: Extract text content from PDF files with accurate parsing
- PDF Merge: Combine multiple PDFs into a single file
- PDF Split: Split PDFs by page range
- Privacy: All processing happens in the user's browser or local environment
- Performance: Rust-powered with WASM for maximum speed
Installation
npm install @jackgreen2018/pdf-engine-wasmOr build from source:
git clone <this-repo>
cd pdf-engine-wasm
npm install
npm run buildUsage
Browser
import pdfEngine from '@jackgreen2018/pdf-engine-wasm';
// Initialize the engine
await pdfEngine.init();
// Get page count of a PDF file
const file = document.querySelector('input[type="file"]').files[0];
const arrayBuffer = await file.arrayBuffer();
const pageCount = await pdfEngine.getPageCount(new Uint8Array(arrayBuffer));
console.log(`Pages: ${pageCount}`);
// Extract text from a PDF
const text = await pdfEngine.extractText(new Uint8Array(arrayBuffer));
console.log(text);
// Merge multiple PDFs
const mergedPdf = await pdfEngine.merge([pdf1Buffer, pdf2Buffer, pdf3Buffer]);
// Split a PDF by page numbers
const pagesToExtract = [1, 3, 5];
const splitParts = await pdfEngine.split(new Uint8Array(arrayBuffer), pagesToExtract);Node.js
const pdfEngine = require('@jackgreen2018/pdf-engine-wasm');
async function processPdf() {
await pdfEngine.init();
const buffer = require('fs').readFileSync('document.pdf');
const pageCount = await pdfEngine.getPageCount(buffer);
console.log(`Pages: ${pageCount}`);
const text = await pdfEngine.extractText(buffer);
console.log(text);
}
processPdf().catch(console.error);Build
npm run buildThis compiles the Rust code to WASM using wasm-pack and builds the TypeScript definitions.
Development
# Install dependencies
npm install
# Build the project
npm run build
# Run benchmarks
npm run benchmark
# Test locally
npm testBenchmark
Performance benchmarks for pdf-engine-wasm operations:
npm run benchmark| Operation | pdf-engine-wasm (ms) | pdf-lib (ms) | |-----------|----------------------|--------------| | Page Count | 0.83 | 1.70 | | Text Extraction | 0.21 | — | | Merge (2 files) | 1.17 | 3.88 | | Split (pages [0,1]) | 0.23 | 1.87 |
extractText correctness: PASS — gated via tests/fixtures/text-fixture.pdf (FlateDecode-compressed, real-world content stream).
Run 2026-08-02 (v1.0.6); raw JSON at benchmark-results.json.
Commercial license & support
For teams or organizations that need the package without MIT attribution obligations, or require a formal SLA, a commercial license is available. See COMMERCIAL-LICENSE.md for pricing and terms. To purchase, email [email protected].
License
MIT
Verify locally
npm install @jackgreen2018/pdf-engine-wasm
node -e '
const fs = require("fs");
const m = require("@jackgreen2018/pdf-engine-wasm");
const buf = fs.readFileSync("test.pdf");
m.initialize().then(() => m.getPageCount(new Uint8Array(buf)))
.then(n => console.log("pages:", n));
'Acceptance Criteria Evidence
| AC | Verifiable requirement | Committed proof |
|---|---|---|
| AC-1 | Real Rust source with lopdf domain dependency compiles to a non-stub WASM artifact; JS and TypeScript declarations build. | Cargo.toml, src/, pkg/, dist/, evidence/cargo-build.log, evidence/wasm-pack-build.log, evidence/gate-artifact.log |
| AC-2 | Rust and package tests pass on the final source. | evidence/cargo-test.log, evidence/npm-test.log |
| AC-3 | The exact npm tarball installs in a clean consumer and page count, merge, and split return valid PDFs with correct page counts. | jackgreen2018-pdf-engine-wasm-1.0.0.tgz, evidence/npm-pack.log, evidence/local-install-smoke.log, evidence/gate-behavior.log |
| AC-4 | A runnable head-to-head benchmark against pdf-lib uses realistic identical input, validates output, and produces real numbers matching README. | benchmark.mjs, evidence/benchmark.log, evidence/benchmark.json, benchmark table above |
| AC-5 | Both required hard gates pass for /apps/pdf-engine-wasm before publication. | evidence/gate-build.log, evidence/gate-behavior.log |
| AC-6 | Scoped package metadata has version, license, repository, correct artifact entry points, and .d.ts; package is public under @jackgreen2018/pdf-engine-wasm. | package.json, evidence/npm-whoami.log, evidence/npm-publish.log, evidence/npm-view.log |
| AC-7 | README provides the install command, working example, measured benchmark table, npm URL, and direct AC-to-evidence index with no unsupported "verified" claim. | This README |
| AC-8 | Final app repository commit is tagged v1.0.6; cycle scratch is absent and no web-deployment artifacts were added. | evidence/git-tag.log |
Launch post
Draft lives at evidence/devto-launch-post.md.
Posting requires a DEVTO_API_KEY (manual step). README's published benchmark
numbers (evidence/benchmark.log) are the source of truth until the dev.to URL exists.
See Also
- pdf-lib — A popular JavaScript PDF library for comparison
