Professionals work with PDFs every day — merging documents, splitting reports, optimizing files for email. Until now, client-side PDF tools have been limited by JavaScript's single-threaded nature and garbage collection overhead.
That's why I built PDF Tool with Rust compiled to WebAssembly. The result? PDF operations that feel instantaneous even with multi-megabyte documents.
The Problem with JavaScript PDF Libraries
Popular solutions like pdf-lib work entirely in JavaScript. They're excellent for small documents, but processing large PDFs (5MB+) in the browser becomes sluggish:
- Merging 3 PDFs can take 1+ seconds
- Splitting a 100-page document feels like waiting
- Optimization requires heavy computation that blocks the main thread
Every operation runs on the JavaScript main thread, freezing the UI and frustrating users.
The Rust/WASM Solution
Rust compiles to WebAssembly with near-native performance. By implementing PDF operations in Rust and exposing them via wasm-bindgen, we get:
Speed: Operations run 2.5-3x faster than pure JavaScript
Responsiveness: No UI blocking even with large documents
Memory efficiency: Rust's ownership model prevents memory leaks
Smaller bundles: Compressed WASM modules load quickly
Performance Benchmarks
Here's how PDF Tool compares against pdf-lib on a 5MB PDF with 100 pages:
| Operation | Rust/WASM (ms) | pdf-lib (ms) | Speedup |
|---|---|---|---|
| Merge | 450 | 1200 | 2.7x |
| Split | 320 | 800 | 2.5x |
| Optimize | 280 | 900 | 3.2x |
The optimize operation also provides 25% size reduction through stream re-encoding, making it ideal for email attachments and storage.
Installation and Usage
npm install pdf-tool
In Browser
import init from 'pdf-tool';
const pdf = await init();
const merged = pdf.merge(pdfData);
const split = pdf.split(pdfData, [1, 5, 10]);
In Node.js
const { merge, split, optimize } = require('pdf-tool');
// Async initialization
const pdfTool = await pdfTool.init();
const merged = pdfTool.merge(buffer);
How It Works
The library uses the pdf-writer crate for PDF generation and manipulation, combined with custom parsing logic for reading and extracting page content. Everything is compiled to WebAssembly via wasm-bindgen, providing seamless JavaScript interop.
The WASM module is streamed and instantiated lazily, so your app doesn't wait for the full PDF library to load before becoming interactive.
Why This Matters
For document-heavy applications — forms processing, report generation, workflow systems — every millisecond counts. Rust/WASM gives you the performance of native code with the convenience of JavaScript, all running safely in the browser with zero server-side processing.
Your files never leave your device. No uploads. No subscriptions. Just $19 for the Pro version with unlimited batch processing.
The Future of PDF Processing
WebAssembly is changing what's possible in the browser. With Rust, we can bring server-grade PDF processing capabilities to client-side applications without sacrificing privacy or performance.
The pdf-tool library is open source and available on npm. Check it out and experience the speed difference for yourself.
Top comments (0)