DEV Community

Cover image for What actually stays local in a browser image editor?
Jackple Shang
Jackple Shang

Posted on Edited on AI-assisted

What actually stays local in a browser image editor?

Most online image editors look the same from the outside: drag a file into a box, wait, and download a result. The architectural difference appears when you ask what happens between those steps.
I built Tubox, a browser-based image toolbox. The selected image is decoded and processed on the user’s device rather than uploaded to an application server. The page, JavaScript, fonts and AI model files still load over the network, but there is no image-upload endpoint.
That constraint changes several engineering decisions.
Batch processing needs backpressure
A simple implementation might decode every dropped file at once and render each one into a canvas. With a folder of phone photos, that quickly becomes a memory problem.
The batch pipeline uses a small pool of Web Workers. The pool is bounded by navigator.hardwareConcurrency minus one, capped at six workers. Jobs wait for a free worker, and decoding, resizing, watermark rendering and encoding happen off the main thread.
The limit is not only about CPU. It also acts as a form of backpressure on decoded pixels. A 50-megapixel photo can consume hundreds of megabytes while it exists as an RGBA bitmap, even if the exported JPEG is small.
Input and output types also need to remain structured-clone compatible. Blobs can cross the Worker boundary; ImageBitmap and functions cannot be passed blindly. Each task has to define what is transferred and what is copied.
Local does not mean no network
The privacy claim needs to be exact. “Images stay on your device” and “the site works completely offline” are different promises.
AI inference needs model files. A useful UX has to expose that first-run download instead of presenting a blank canvas that looks frozen. In Tubox, models load only when the relevant tool opens. Batch processing has no model dependency and can start immediately.
The same distinction applies to fonts and application chunks. A privacy-first product should describe the data flow precisely:
The selected image is not uploaded.

The page and model assets are downloaded.

Processing and export happen in the browser.

No account or server-side image library is created.

That wording is less impressive than “100% offline”, but it is testable and easier for users to trust.
AI inference needs an honest fallback path
WebGPU is the preferred backend for background removal and upscaling. Device and browser support is uneven, so the application tries WebGPU and falls back to WebAssembly.
The fallback is not invisible magic. A first inference may be slow, especially on an older phone. A progress callback and cancellation path matter as much as the model choice. Users need to know whether the app is downloading, loading a model, or actually processing pixels.
For transparent upscaling, edge colours must be extended before inference and the alpha channel handled separately. Otherwise transparent pixels can bleed dark or coloured halos into the subject.
EXIF removal without recompression
Re-encoding an image just to remove metadata is wasteful. JPG, PNG, WebP and GIF use container structures that can be scanned for metadata segments.
The workflow is:
Parse the container.

Identify EXIF, XMP, IPTC, comments or PNG text chunks.

Remove the relevant segments.

Rebuild the container while preserving required structural data.

This approach avoids another lossy encode. It also exposes edge cases: orientation can live in EXIF, and ICC data affects colour interpretation. Removing everything may be correct for one workflow and wrong for another.
What I would test next
The highest-value feedback is no longer “does it support another format?” It is whether the first real workflow is understandable on a phone:
Can a user tell when a model is downloading?

Can they recover if an inference backend fails?

Does the file actually download on Safari?

Does the result remain usable at the target file size?

Those questions are specific enough to test and fix. That is more useful than another feature card.
Try it: https://tubox.top/en
Source, licensed AGPL-3.0: https://github.com/jackple/tubox
Practical guides: https://tubox.top/en/guides/

Top comments (0)