How it works
Files never leave your device. Here's exactly what happens when you convert.
What happens when you drop a file
Your browser reads the file.
The browser's File API reads your file into memory as an ArrayBuffer. No network request is made. The data stays in your browser tab's isolated memory.
A WASM module processes it.
The relevant WebAssembly module (libvips for images, ffmpeg for video, etc.) is loaded once and cached. On first use, it downloads; after that, it loads instantly from your browser cache. The module runs on your CPU in a sandboxed Web Worker, so it can't access anything outside the tab.
Output is handed back to the browser.
The converted file is an ArrayBuffer in memory. The browser creates a local object URL (
blob:) and serves your download from it. Nothing is sent anywhere.Memory is freed.
After download, the object URL is revoked, and the ArrayBuffers are garbage collected. Your file data is gone from memory. Closing the tab guarantees cleanup.
The libraries under the hood
libvips
Images (JPG, WebP, AVIF, PNG, HEIC, TIFF)
A fast image processing library for various image formats (JPG, WebP, AVIF, PNG, HEIC, …). It is about 5 times faster than ImageMagick for most operations and compiled to ~3MB WASM.
ffmpeg.wasm
Video and audio (MP4, MP3, GIF, WebM, WAV)
ffmpeg.wasm: ffmpeg the industry standard multimedia library, now compiled to WebAssembly for use within SharedArrayBuffer workers (AJA).
pdf-lib + mupdf-wasm
PDF creation, merging, splitting, rendering
pdf-lib handles construction and modification of PDFs in pure JavaScript code. mupdf-wasm is then used for rendering of PDFs to the screen, i.e., rasterization.
@huggingface/transformers
AI tools (background removal, upscaling, alt-text)
Runs ONNX models in-browser using WebAssembly and WebGPU. Models are downloaded once and then cached locally on subsequent uses.
Why WebAssembly, not JavaScript?
JavaScript is very fast for UI-level work on web pages, but it is not suitable for byte-intensive tasks like video encoding, RAW image processing, etc., that have a large performance gap compared to native code written in languages like C, C++, or even Rust (10–100× faster).
WebAssembly is a new binary instruction format that gets compiled to native machine code by the browser at load time. It runs in the same sandboxed environment as JavaScript code, but with near-native performance. The security model for WASM code is that no library can access things like the file system, camera, network, etc. outside of the region of memory it has been granted.
The major tradeoff here is that WASM modules are large (libvips is ~3MB, ffmpeg.wasm is ~25MB). We lazy-load modules in this context and then aggressively cache them so we only pay this once for each user interaction.
Batch conversion
In batch mode, all tools convert files in pools of Web Workers. By default, there are as many Web Workers as there are CPU cores. All files of a tool are converted in parallel up to the number of Web Workers and then put into a queue. So, a batch of 1,000 images will convert in a few minutes on a current laptop.
In practice, the RAM of your device limits the number of files you can batch. A 1,000-file batch of 2MB images requires about 2GB of RAM at peak. Modern laptops have plenty of RAM, while older phones might have problems with 100–200 files. We then warn you when memory pressure is approaching.
Verify it yourself
Open DevTools, switch to the Network tab, and filter for XHR/Fetch requests. Execute conversion of a file, and you will see the WASM module loading once, but that's all. There are no POST requests, no uploads, no calls to remote servers.
This is verifiable. The source is what it is.