Tools
Blog
Sign InSign Up
Blog|Engineering

How to Compress Images Client-Side Without Uploading to a Server

Browser-based image compression using Canvas API and WebAssembly is faster, more private, and equally effective. Here's how ElevenTools does it.

July 26, 2026 5 min read

The Problem With Traditional Image Compression


Every time you upload an image to a "free" compression tool online, you're sending your private photos to a third-party server — often running in a jurisdiction with different privacy laws than your own. These files get stored in cloud buckets, processed by workers, and sometimes used for AI training datasets without your knowledge.


There's a better way. Modern browsers are more powerful than most developers realize. Using the Canvas API combined with strategic JPEG re-encoding, you can achieve 60–80% file size reduction with barely perceptible quality loss — entirely within the user's browser.


How It Works: Canvas API Compression


The Canvas API approach is elegantly simple:


async function compressImage(file, quality = 0.8) {

return new Promise((resolve) => {

const img = new Image();

const url = URL.createObjectURL(file);


img.onload = () => {

const canvas = document.createElement('canvas');

canvas.width = img.naturalWidth;

canvas.height = img.naturalHeight;


const ctx = canvas.getContext('2d');

ctx.drawImage(img, 0, 0);


canvas.toBlob(

(blob) => {

URL.revokeObjectURL(url);

resolve(blob);

},

'image/jpeg',

quality // 0.0–1.0

);

};


img.src = url;

});

}


The quality parameter controls the JPEG compression ratio. A value of 0.8 typically reduces file size by 40–60% with no visible degradation. For thumbnails or web previews, 0.6 can yield 70–80% reductions.


WebP: The Better Format


For modern browsers (Chrome, Firefox, Edge, Safari 14+), converting to WebP instead of JPEG delivers 25–34% better compression at equivalent quality:


canvas.toBlob(blob => resolve(blob), 'image/webp', 0.85);


ElevenTools Image Compressor defaults to WebP output when the browser supports it, falling back to JPEG for older Safari versions.


Handling Large Files: Worker Threads


For files above 10MB, performing compression on the main thread can freeze the UI. Image Compressor uses Web Workers to offload processing:


// compression.worker.js

self.onmessage = async ({ data: { imageData, quality, format } }) => {

const blob = await compressImage(imageData, quality, format);

self.postMessage({ compressed: blob });

};


This keeps the interface responsive even when compressing 50MB raw photographs.


Privacy Guarantees


None of your images ever leave your device. The entire pipeline runs in your browser's JavaScript engine. The file is loaded into memory, processed through Canvas, and the result is handed directly back to you as a download.


ElevenTools stores zero bytes of user images on any server. This isn't just a promise — it's architecturally enforced.


Try It Yourself


Image Compressor is available at /image-tools-compressor — free, no sign-up required, and no file size tracking beyond the browser's own memory limits.

Share: