TL;DR: When a tool says your files never leave your device, that is an architectural claim, not a marketing one. Here is the stack that makes it true, and what it costs.
Most online file converters follow the same shape. Your browser uploads the file, a server runs something like ImageMagick or headless FFmpeg, and you get a download link. The work is real, and often fast. The catch is that your file left your machine, and it now sits in storage you do not control, under a retention policy you did not agree to.
A browser-based tool keeps the same user experience and removes the server. Reading the file, processing it and writing the result all happen inside the tab. That is not a small variation on the upload model. It removes a whole class of problems, because there is no transfer to intercept, no queue to wait in and no retention window to think about.
Two architectures, same three steps
| Step | Server-based tool | Browser-based tool |
|---|---|---|
| Reading the file | Copied into their storage | Read by the File API, stays local |
| Processing | Their CPU, usually queued | Your CPU, inside the tab |
| Result | A download link that expires | A Blob, ready immediately |
| Who can read the file | Anyone with access to their storage | Only you |
WebAssembly is the reason this works at all
WebAssembly is a compact binary format that runs at close to native speed inside a sandboxed virtual machine. Engines written in C, C++ or Rust are compiled to it and shipped as ordinary static files.
The important part is that these are the real engines, not reimplementations:
- qpdf for PDF encryption and decryption
- FFmpeg for video and audio
- Tesseract for OCR
- pdf-lib and PDF.js for reading and writing PDFs
- OxiPNG for lossless PNG optimization
A video encoded by the FFmpeg build in your tab is FFmpeg output, not a web approximation of it. That matters more than it sounds, because the old failure mode of browser tools was that they quietly did something worse than the desktop tool you were comparing them against.
Real first-load sizes, since these are files you actually download:
| Engine | First-load size |
|---|---|
| FFmpeg core (video and audio) | about 30 MB |
| Tesseract plus English data | about 6.7 MB |
| qpdf WebAssembly | about 1.3 MB |
| PDF.js worker | about 1.4 MB |
That is code, not your file. It is cached after the first run, and it does not grow with the document you feed it.
Canvas covers everything pixel-related
Images are the one category that does not need WebAssembly. The Canvas API exposes the same kind of drawing surface a native editor uses. createImageBitmap decodes a file, a canvas holds the pixels, and toBlob encodes the result back out to PNG, JPEG, WebP or AVIF. Cropping, resizing, watermarking and format conversion are pixel operations on that surface.
For PNG output you can pair Canvas with OxiPNG, which re-compresses the file losslessly instead of throwing quality away.
Web Workers keep the tab responsive
Heavy work on the main thread freezes the page, so long jobs belong in a Web Worker, a background thread with no DOM access. Video tooling hands work to FFmpeg inside a worker and receives log lines and progress events back, which is why the progress bar keeps moving while the encoder is busy.
One detail worth stealing: a single-threaded Tesseract build does not need SharedArrayBuffer, and therefore does not need the COOP and COEP headers that multi-threaded WebAssembly builds usually force on your whole site. Slightly slower per page, much smaller deployment constraint.
File and Blob are what replace the upload
This is the part that actually removes the network call. Slightly simplified, but this is the shape of the pipeline:
// Bytes come from disk into the page. No fetch, no POST.
const bytes = new Uint8Array(await file.arrayBuffer());
// Hand them to an engine running in the tab.
const output = await engine.run(bytes);
// Build the result and hand it back as a download.
const blob = new Blob([output], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
The bytes travel from disk to memory and back. There is no code path in that loop that talks to a network. It also means there is no upload size limit imposed by a server, only the memory limit of the device.
Verify it yourself in two minutes
Do not take the privacy line on a tool page on faith. Check it:
- Open DevTools, go to the Network tab, and clear it.
- Process a file.
- Look at what showed up.
You will see the page, its CSS and its JavaScript, the engine on the first run, and web fonts. You will not see your document. Analytics scripts will also appear, and they report that a page was viewed, not what was in the file.
The stronger test: finish one run so the engine is loaded, then disconnect from the network and process another file without reloading. If it still works, the processing path never touched a server.
What it costs
Local processing is not free, and the honest version is worth stating:
- A cold start is slow. The first run downloads the engine. On a slow connection that is a real wait.
- Memory is the ceiling. Everything lives in one tab. A desktop tool streams a large file from disk, a browser tab has to hold it. Some tools publish a hard cap for exactly this reason.
- A server can be faster. Video encoding is CPU-bound, and a browser build falls back to software encoding rather than a hardware encoder, so it does not get the GPU speedup a native build can use.
For a few megabytes of PDF or a one minute clip, none of this is felt, and you get privacy plus no quotas. For a two hour 4K recording, a desktop tool is the better answer, and it is worth saying so instead of pretending otherwise.
Where the model breaks
There is a category of job a browser tab cannot do: anything that depends on a large model. Background removal, object erasing and generative upscaling need weights that no reasonable page load budget covers, so those run on a server and the image is uploaded. A tool that does this should say so on the page, not in a footnote.
That is the useful test to apply to any tool that claims to be private. If it names a real engine and runs it in the tab, the file stays put. If it needs a bigger model than a browser can hold, it uploads, and it should admit it.
This post also lives on my blog at aihangsoft.top, where I build browser-based file tools that work this way.
Top comments (0)