DEV Community

Cover image for I built a free image compressor that never uploads your files
Gaurav Bhowmick
Gaurav Bhowmick

Posted on

I built a free image compressor that never uploads your files

Every free image compressor I tried had the same problems: they upload your images to some server, limit you to 5 files a day, or force you to create an account.
I just wanted to drop images, compress, download. So I built one.
Meet MiniPx
minipx.com — a free image compressor that runs 100% in your browser. Your images never leave your device.
How it works
The compression engine uses the HTML5 Canvas API. Here's the core idea:

  1. Load the image into a Canvas element
  2. Re-encode it at a lower quality using canvas.toBlob()
  3. If the output is larger than the original (happens with PNGs), try progressively lower quality settings
  4. If WebP still can't beat the original, fall back to JPEG
  5. Always return the smallest successful result

Code:
// Simplified version of the multi-pass compression
async function compress(file, quality, format) {
const img = await loadImage(file);
const canvas = document.createElement('canvas');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);

// First pass
let blob = await canvasToBlob(canvas, format, quality);

// Smart fallback if output is larger
if (blob.size >= file.size) {
for (const q of [0.6, 0.45, 0.3, 0.2]) {
const attempt = await canvasToBlob(canvas, format, q);
if (attempt.size < file.size) {
blob = attempt;
break;
}
}
}
return blob;
}

The key insight: Canvas API quality values aren't linear. Quality 0.92 barely compresses anything. Quality 0.65 (our "Smart" preset) gives 50-70% reduction with no visible quality loss.
Features

Compress — Gentle (20-40%), Smart (50-70%), Tiny (75-90%)
Convert — WebP, JPEG, PNG in any direction
Resize — Set max width to 1920, 1280, or 800px
Batch — No file limits, process as many as you want
Private — Zero server uploads, works offline

Tech stack

Next.js 15 (static export)
React 19
Canvas API for compression
Deployed on Netlify (zero server cost)

What I learned
Canvas API quality is not what you think. I initially set the "Smart" preset to quality 0.78 thinking that's decent compression. A 3MB PNG screenshot compressed to 3.2MB — larger than the original. Turns out 0.78 is barely any compression for the Canvas encoder. Dropping to 0.65 fixed everything.
The multi-pass approach matters. A single-pass compressor will sometimes produce files larger than the original, especially with PNG screenshots. The fallback chain (try lower quality → try different format) ensures the output is always smaller.
Static sites are underrated for tools. MiniPx costs $0/month to run. No server, no database, no file storage, no bandwidth costs. The entire thing is HTML/CSS/JS served from a CDN.
Try it
minipx.com — would love your feedback. What features would you want added?

Top comments (0)