Technology Aug 27, 2026 · 3 min read

Building a PDF Toolkit That Never Touches a Server

Every PDF tool follows the same pattern: upload your file, wait, download the result. That server round-trip exists because PDF processing is genuinely expensive — parsing a file format never designed to be edited, re-encoding pages, running compression. Doing that in a browser tab used to mean eith...

DE
DEV Community
by WebsiteGeek
Building a PDF Toolkit That Never Touches a Server

Every PDF tool follows the same pattern: upload your file, wait, download the result. That server round-trip exists because PDF processing is genuinely expensive — parsing a file format never designed to be edited, re-encoding pages, running compression. Doing that in a browser tab used to mean either a thin wrapper around a server API, or nothing at all.

That's changed. WebAssembly-compiled versions of real PDF libraries are fast enough now to run entirely client-side, and building DeskRamp meant figuring out what that actually takes inside a Chrome extension, not just a regular web page.

The CSP wall

Manifest V3 extensions get a strict default Content Security Policy, and WebAssembly needs an explicit exception to run at all:

"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
}

Without 'wasm-unsafe-eval' explicitly declared, WebAssembly.instantiate() throws immediately — Chrome treats compiled WASM the same security-sensitive way it treats eval(), since both execute code the browser can't statically analyze ahead of time. This is a one-line fix once you know it's needed, but it's the first thing that breaks silently if you're porting WASM-based processing into an extension for the first time.

Picking a library per task, not one library for everything

No single library covers merge, split, compress, convert, and e-Sign well. DeskRamp bundles a few, each doing the one thing it's actually good at:

pdf.js — rendering and reading PDF structure
pdf-lib — merging, splitting, and building new PDF documents
qpdf (compiled to WASM) — the actual compression and password/decryption work, which needs low-level access to PDF's internal object structure that higher-level libraries don't expose
docx / pptxgen / xlsx libraries — format conversion into and out of Office formats

This means the extension ships several hundred KB to a few MB of vendored library code, which matters for install size and initial load time. The practical fix is lazy-loading: nothing pulls in qpdf's WASM binary until the user actually clicks "Compress," rather than loading every processing library up front for a toolkit most of a session won't touch.

The real ceiling: browser tab memory, not CPU

The unexpected constraint wasn't processing speed — modern WASM PDF processing is fast enough that a merge or split feels instant on anything but a huge file. It's memory. A browser tab has a much lower practical memory ceiling than a server process does, and a large multi-hundred-page PDF fully parsed into memory, plus the WASM runtime's own working memory, plus whatever else the tab is holding, can hit that ceiling in a way a server-side version of the same operation never would.

The mitigation is processing in chunks where the library supports it (streaming page-by-page rather than materializing the whole document object graph at once) and being explicit about releasing references (ArrayBuffers, typed arrays) as soon as a stage finishes, rather than trusting garbage collection to catch up on its own timeline while a multi-step operation is still running.

Why this is worth the extra complexity

The upload step in a typical PDF tool isn't just slower — it's the whole reason people hesitate to use these tools for anything they'd actually rather not hand to a server: contracts, IDs, financial documents. Once WASM-based processing is fast enough to feel native, there's no real reason left to default to a server round-trip for tasks like merge, split, compress, and convert. The extra engineering constraints (CSP, bundle size, memory ceilings) are the actual cost of that tradeoff — worth paying once, not something that needs solving per-feature.

If you're curious what this looks like shipped: DeskRamp is free on the Chrome Web Store.

DE
Source

This article was originally published by DEV Community and written by WebsiteGeek.

Read original article on DEV Community
Back to Discover

Reading List