WebAssembly Browser Apps: How Local File Processing Became Possible

For most of the web's history, serious file processing had to happen on a server, because a browser could only run JavaScript and JavaScript was not where anyone had written a PDF engine or an OCR system. WebAssembly changed the arithmetic. It is a portable binary instruction format that browsers execute inside the same sandbox as a web page, at speeds close to native code. It was never meant to replace JavaScript; it exists so that the decades of compiled libraries the world already depends on can run somewhere they previously could not.

The path is fairly direct. A toolchain compiles existing C or C++ source into a WebAssembly module rather than a platform executable, and the module operates on a linear memory space, which is essentially one large array of bytes it treats as its heap. JavaScript in the page allocates that memory, copies your file into it, calls an exported function, and reads the result back out. From the library's point of view very little has changed. From the page's point of view, a battle-tested engine has suddenly become a callable function with no server involved.

The architectural consequence is what matters most for privacy. Once the engine runs in the tab, the server's only job is to deliver static files: the page, the script and the module. Your document is opened by the browser, held in that memory space, processed and written back out as a download, and it never becomes a request body travelling across the network. This is a structural guarantee rather than a policy promise, and it is verifiable: open the network panel of your developer tools, do the work, and watch for an upload that does not happen.

It is worth being honest about the costs. The module has to be downloaded and compiled before the first operation, so there is a startup delay that a server-side tool hides behind its own hardware. Everything runs on your device, which means a phone from several years ago will be slower than a workstation, and very large files are bounded by how much memory the tab can obtain. Heavy work also needs to be moved into a worker thread so the interface stays responsive. These are real trade-offs, and for most document tasks they are comfortably worth paying.

This is exactly how PdfWill is built. The PDF work runs on WebAssembly builds of established engines, with pdf-lib and pdf.js handling document structure and rendering, qpdf-wasm handling deeper structural operations, and tesseract.js performing recognition when you run OCR. That last one is the clearest illustration of the trade: OCR feels slower than a cloud service because your own processor is genuinely doing character recognition, page by page. In exchange, a scanned contract becomes a searchable PDF, and merge, split, compress and protect all complete, without a single page ever leaving your machine.

Related tools