Why we built ToolBox Image to run entirely in your browser
A walkthrough of the architecture behind a privacy-first image toolkit — and why the browser turned out to be the right place for it.
Most free online image tools work the same way: you upload a file to their server, the server processes it, and you download the result. That model is simple to build, but it comes with hidden costs — your privacy, their server bills, and limits on file size and throughput.
ToolBox Image takes a different approach. The entire application — decoding, encoding, compression, resizing, format conversion — runs in your browser. There is no server to upload to. Your images never leave your device. This architecture was a deliberate choice, and it shaped every decision we made about the product.
Why the browser-first approach?
The obvious alternative is a traditional server-side architecture. You upload an image, the server runs it through a tool like ImageMagick or Sharp, and sends the result back. This works, but it creates a set of problems that are hard to solve:
- Privacy. Users have to trust that you won't store, analyse, or leak their images. For sensitive documents — medical images, design mockups, personal photos — that trust is hard to earn.
- Cost. Every compression runs on your infrastructure. The more successful you are, the more you pay. This creates pressure to limit file sizes, add queues, or introduce paid tiers.
- Latency. Uploading a 100 MB file over a slow connection takes minutes before processing even starts. For users in regions with poor connectivity, the tool is effectively unusable.
- Scale. A single server can handle dozens of concurrent compressions. But what about thousands? You need auto-scaling groups, load balancers, CDN upload endpoints — all of which add complexity and cost.
The browser-first model solves all of these at once. Processing is free (the user's CPU cycles), private (no data leaves the device), and infinitely scalable (every user brings their own hardware).
Making it work: WebAssembly and Web Workers
Ten years ago, running image codecs in the browser was impossible. Today, WebAssembly lets us compile C and Rust libraries directly to a format the browser can execute at near-native speed. We compile Mozilla's mozJPEG, Google's libwebp, and the libaom AVIF encoder — all written in C — to WebAssembly. The browser runs them as efficiently as if they were installed natively.
But single-threaded encoding is slow for large batches. That is where Web Workers come in. Each worker runs on a separate CPU core, and we spawn as many workers as the device has cores. On a modern laptop with 8 cores, that means 8 images compressing simultaneously. A batch of 200 photos that would take minutes on a single thread finishes in seconds.
What we gave up
The browser-first approach is not free. The most significant trade-off is memory. The browser tab has access to the device's RAM, but a single tab crashing because an image exceeded available memory is a bad experience. We cap individual files at 100 MB and batch sizes at 200 files to stay within safe limits.
We also gave up server-side features like persistent storage, email delivery, and analytics. There is no database of compressed images, no email newsletter, no tracking of which formats users prefer. This is philosophically consistent with our privacy stance, but it means we cannot offer features like "recent compressions" or "saved presets between sessions."
What's next
The browser is becoming a legitimate runtime for performance-sensitive applications. As WebAssembly gains garbage collection, threading, and SIMD support, more of the application stack can move client-side. We are exploring WebGPU for even faster pixel processing and the File System Access API for seamless folder integration.
For now, the compressor is live and processing thousands of images per day — all of them staying right where they belong.