DEV Community

Profiterole
Profiterole

Posted on

Build a Privacy-First Image Compressor That Runs Entirely in Your Browser

The Problem

Every online image compressor uploads your files to a server. That means:

  • Your images pass through someone else's infrastructure
  • Compression takes time due to upload/download
  • Privacy-sensitive images (screenshots, documents) leave your device

The Solution: Canvas API

The HTML5 Canvas API can compress images entirely in the browser. No server. No upload. Your images never leave your device.

Here's the core technique:

function compressImage(file, quality = 0.7, maxWidth = 1920) {
  return new Promise((resolve) => {
    const img = new Image();
    img.onload = () => {
      const canvas = document.createElement("canvas");
      let { width, height } = img;

      // Resize if needed
      if (width > maxWidth) {
        height = (height * maxWidth) / width;
        width = maxWidth;
      }

      canvas.width = width;
      canvas.height = height;
      const ctx = canvas.getContext("2d");
      ctx.drawImage(img, 0, 0, width, height);

      canvas.toBlob(resolve, "image/jpeg", quality);
    };
    img.src = URL.createObjectURL(file);
  });
}
Enter fullscreen mode Exit fullscreen mode

Key Insights

Quality vs File Size

  • 0.8 quality: Usually 60-70% smaller with minimal visible difference
  • 0.6 quality: 80%+ smaller, noticeable on close inspection
  • 0.4 quality: Aggressive compression, good for thumbnails

Format Matters

  • JPEG: Best for photos (lossy, great compression)
  • WebP: 25-35% smaller than JPEG at same quality
  • PNG: Lossless — Canvas can't truly compress PNGs

Batch Processing

Use Promise.all() with a concurrency limit to compress multiple files without freezing the browser:

async function batchCompress(files, quality, concurrency = 4) {
  const results = [];
  for (let i = 0; i < files.length; i += concurrency) {
    const batch = files.slice(i, i + concurrency);
    const compressed = await Promise.all(
      batch.map(f => compressImage(f, quality))
    );
    results.push(...compressed);
  }
  return results;
}
Enter fullscreen mode Exit fullscreen mode

Try It

I built a free, open-source image compressor using this technique:

Browser Image Compressor — drag and drop, batch processing, quality control, ZIP download. Zero server uploads.

Also check out the OG Image Generator for creating social media cards.


All tools at Profiterole Dev Tools

Top comments (0)