How a file converter can run entirely in your browser

WebAssembly, the File API, canvas, Web Workers and object URLs, explained without hand-waving — plus a thirty-second test you can run yourself to confirm your file never left the tab.

A file converter needs to do three things: read the bytes of a file, change them, write new bytes back out. All three have had browser APIs for years, so the server in the middle is optional. Reading is the File API. Changing is JavaScript, or a C library compiled to WebAssembly. Writing back is a Blob and an object URL. Put those together and a PDF merger or a 50 KB image compressor runs on your own CPU with the network switched off.

The interesting part is not that this works. It is that you can check it works in about thirty seconds, without trusting anybody's privacy page.

The five pieces

Reading: the File API

An <input type="file"> hands your page File objects. A File is a Blob with a name, and a Blob gives you .arrayBuffer(), .text() and .stream(). Picking a file implies nothing about sending it anywhere; the browser is giving the page a read-only handle to bytes already on your disk.

const file = input.files[0];
const buf  = await file.arrayBuffer();   // bytes, in this tab's memory

From there it is ordinary programming: parse a PDF header, read a ZIP central directory (an .xlsx is a ZIP), decode a JPEG.

Reshaping images: canvas

Canvas is the resize-and-recompress engine. Draw the image at the size you want, then ask the canvas for new bytes.

const bmp = await createImageBitmap(file);
const c   = new OffscreenCanvas(800, Math.round(800 * bmp.height / bmp.width));
c.getContext("2d").drawImage(bmp, 0, 0, c.width, c.height);
const out = await c.convertToBlob({ type: "image/jpeg", quality: 0.72 });

That quality argument is the whole trick behind "get this photo under 50 KB": binary-search it between 0.30 and 0.95 until out.size fits the limit. Six or seven encodes, roughly 200 ms on a mid-range phone. That is exactly what Reduce Image Size does.

Everything canvas cannot do: WebAssembly

Canvas cannot read a PDF or recognise text. That is where WebAssembly earns its place: existing C and C++ code compiled to a binary the browser runs at close to native speed. Tesseract is the clearest case, a twenty-year-old OCR engine executing inside a tab. On this site the Tesseract core is a 3.8 MB WASM bundle and the English model is another 2.9 MB gzipped.

Plenty of work needs no WASM at all. pdf-lib (page editing), PDF.js (rendering) and SheetJS (spreadsheets) are plain JavaScript.

Keeping the tab usable: Web Workers

JavaScript on the main thread is also the thread that paints your UI. Run OCR there and the tab locks: no scrolling, no cancel button, and eventually Chrome offers to kill the page. A Worker is a second thread with its own memory, talking to the page by messages.

const w = new Worker("/static/js/ocr-worker.js");
w.postMessage({ buf }, [buf]);          // transfer ownership, don't copy
w.onmessage = e => showText(e.data.text);

That second argument to postMessage matters more than it looks. Listing the ArrayBuffer as transferable moves it instead of cloning it, which for a 40 MB scan is the difference between a freeze and a hitch.

Handing back the result: object URLs

URL.createObjectURL(blob) returns a blob: URL that points at memory in your tab. Set it as the href of an <a download> and the browser saves a file. It never resolves over the network, because blob: is not HTTP.

const url = URL.createObjectURL(out);
link.href = url; link.download = "photo.jpg";
// when the user clears, or you replace the result:
URL.revokeObjectURL(url);

Skipping revokeObjectURL is the most common leak in tools like these. Convert fifty images without revoking and the tab is still holding all fifty results.

What "nothing is uploaded" actually means

It means no request carries your file's bytes in its body. It does not mean the page makes no requests, and any tool claiming that is lying. Loading the page fetches HTML, CSS, JavaScript, the WASM binary and the OCR model. Those are downloads: code coming to you.

What crosses the network Direction Contains your file?
HTML, CSS, JS bundle down no
pdf-lib / SheetJS / Tesseract WASM down no
OCR language model (.traineddata.gz) down no
Analytics ping on page view up no, page path only
Ad requests on content pages both no
Your document none never sent

Verify it yourself

  1. Open a tool page, press F12, and switch to the Network tab.
  2. Let the page finish loading, then press the clear button in the Network toolbar. Everything after this is caused by you.
  3. Run the conversion.
  4. Read the Size column and check the request payloads. A server-side converter shows a POST whose body is roughly your file's size: a 3 MB PDF makes a 3 MB request, or about 4 MB if it is base64-encoded. A browser tool shows nothing, or a few hundred bytes of analytics.

The blunter test takes ten seconds. Load the page, switch on airplane mode (or set Network throttling to Offline in DevTools), then use the tool. If it still converts your file, the conversion is happening on your device, because there is nowhere else left for it to happen.

Two honest caveats about that test. Some tools fetch a library or a model on first use rather than at page load, so the first offline attempt can fail while a second, after the cache is warm, succeeds. And a service worker could in principle make a genuinely server-backed tool look offline-capable by queueing the upload for later, so do the Network check as well, not only airplane mode.

The trade-offs

Your device is the server now, with everything that implies.

Memory. A 400-page scan at 300 dpi is several gigabytes once decoded to pixels. A desktop tab typically gets 2–4 GB before the browser gives up; iOS Safari is far stingier and tends to reload the page without a useful error. Splitting the file first with Split PDF usually fixes it.

First load. OCR means about 6.7 MB of engine and model before the first character appears. On a slow connection that is twenty to thirty seconds of apparently nothing happening. It is cached afterwards, but the first visit is the one people judge.

Raw power. A server can put sixteen cores and a GPU behind OCR and reply in under a second. In a browser, a dense A4 page takes a few seconds on a laptop and considerably longer on a budget phone. If you have ten thousand pages to process, a browser tool is the wrong tool.

Missing toolchains. No ImageMagick, no Ghostscript, no LibreOffice. So legacy binary .doc is out (only .docx, which is a ZIP full of XML), CMYK and PDF/X colour work is out, and some font edge cases render differently than they would in Acrobat. An honest browser tool has a shorter feature list than a server one, not a longer one.

Nothing to resume. Close the tab and the work is gone. There is no job queue, no email-me-when-done, no history.

Browser-side Server-side
Your file leaves the device no yes
Works offline after load mostly no
Practical file size ceiling ~100–300 MB limited by the plan
OCR speed, one A4 page 2–8 s under 1 s
Batch of 5,000 files not realistic routine
Cost to run near zero per gigabyte

What a site like this still collects

Not your files, but not nothing either. Page views are counted with first-party, cookie-free analytics: the page path, the referring site's domain, device type, browser and OS family, and an anonymous code derived from a one-way hash that is re-salted every day. No IP address is stored, and because the salt changes daily there is no way to stitch two days of activity into one person. Statistics are kept for up to 13 months.

Two assumptions people get wrong. First, "no cookies" is true of the analytics, not of the advertising: ad partners on content pages may set their own cookies, which is why there is a banner with an Essential only option. Second, tool usage is counted, but only the tool's name, once per run. Never file names, sizes or results. The privacy policy spells out each item, and the full set of tools is at /tools/.

Frequently asked questions

Is browser-side processing less accurate than a server? For images, PDFs and spreadsheets, no, because it is often the same library. For OCR, usually yes: a server can afford a large neural model, while a browser needs one that downloads in a few megabytes.

If I lose internet halfway through, does the tool break? For most tools, no. Once the page and its libraries are loaded, the conversion needs no network. A dropped connection during the initial model download is a different matter, and you will get a clear failure.

Can a browser tool still leak my data some other way? In principle, yes, which is why the Network tab test is worth doing rather than taking anyone's word. A page with a third-party script has to be trusted not to read the page's variables; that is a reason to prefer tools that load their libraries from their own domain.

Does this work on a phone? Small jobs, yes. Anything over roughly 30 MB, or OCR across many pages, will hit memory limits on mid-range Android and on iOS. Do those on a laptop.

B

Written by Bablu Kumar Jha

Founder, BeeProton AI · Mumbai, Maharashtra, India

Related posts