Running Pandoc in the Browser: WebAssembly, Web Workers, and a 58 MB Module
Every "convert my document" tool I've tried has the same shape: you pick a file, it uploads somewhere, a server does the work, you get a download link back. That's fine for public data. It's a much worse deal when the file is a contract, a manuscript, a medical record, or anything else you'd rather not hand to a stranger's S3 bucket. So I built a Word→Markdown converter that never uploads…
Running Pandoc in the Browser involves using WebAssembly, Web Workers, and a 58 MB module. The goal is to enable document conversion without uploading the file to a server, making it suitable for sensitive files like contracts and medical records.
Pandoc, a Haskell-based document converter, is chosen over HTML parsing solutions because it preserves document semantics by converting formats into a typed abstract syntax tree and then back into the target format. This means features like footnotes, citations, math, and formatting remain intact.
However, the 58 MB size of the WASM build for Pandoc is too large for initial page load, so it is loaded lazily when the user actually initiates the conversion. The module is downloaded in the background and executed in a Web Worker to keep the UI responsive.
Compiling such a large module is the slowest part, so a caching mechanism is used to avoid recompilation on subsequent loads. IndexedDB, Cache API, and streaming downloads are used to store and retrieve the compiled module efficiently.
WASM modules need a filesystem, so the uploaded file is written to a virtual filesystem before running Pandoc. There are some format-specific considerations, such as GitHub-flavoured Markdown and table generation for CSV and TSV files.
A limitation of this browser-based solution is the inability to convert LaTeX to PDF, as it requires a separate LaTeX engine, which is not practical in WebAssembly. For this use case, the CLI version should be used instead. However, for converting Markdown to PDF, the browser's print pipeline with paged CSS provides a functional solution.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.