TL;DR β I built Shrinkray: a free, open-source image compressor & converter that runs **100% in your browser. No uploads, no servers, no tracking. Your images never leave your device.
The problem
Most "free" online image compressors upload your photos to a server you don't control. For screenshots, IDs, receipts, or product shots, that's a privacy risk you don't need to take.
Shrinkray
Shrinkray does everything client-side using the Canvas API. Nothing is ever uploaded.
Features
- π 100% local β files never leave your browser
- πΌοΈ Convert between WebP / JPEG / PNG / AVIF
- ποΈ Quality slider + optional resize
- π¦ Batch mode β drop a whole folder, download all as a zip
- π Paste from clipboard
- π Per-image and total savings %
- β‘ Installable PWA, works offline
- π MIT licensed, zero build step (vanilla JS)
In my tests it gets ~85β90% size reduction on photo-like PNGs by converting to WebP, with no visible quality loss.
How it works
Drag images in β pick a format and quality β Shrinkray re-encodes each one with canvas.toBlob() and shows you exactly how much you saved. Everything happens on the main thread in plain JavaScript β no frameworks, no dependencies beyond JSZip (CDN) for the "download all" zip.
Try it
- β Code & README: https://github.com/CopilrGiiiTh/shrinkray
- π Live demo: https://copilrgiiith.github.io/shrinkray/
It's fully open source β issues, stars, and PRs welcome. Would love feedback on which formats/options you'd want next (thinking: drag-to-reorder, EXIF stripping toggle, and an AVIF quality preset).
Built with vanilla JS and a lot of canvas.toBlob(). π¦
Top comments (2)
Local-first is a strong selling point for image tools. People often compress IDs, receipts, product photos, or private screenshots without thinking about where the file goes. Making the privacy boundary simple - nothing leaves the browser - is the kind of UX copy that actually matters.
β Nice work! I built something similar at compressfast.site. A few technical things I learned the hard way:
β - HEIC decoding β heic2any doesn't work inside Workers (references window). Keep it on the main thread.
β - AVIF encoding β @jsquash/avif works but WASM is heavy (~700KB). Only load it when the user actually selects AVIF output.
β - Target KB mode β Users love "compress to exactly 200KB." Binary search on quality with PNG output is tricky because quality doesn't linearly affect PNG size. I ended up using color bit-depth reduction + oxipng for this case.
β - Progressive JPEG β Canvas API can't encode progressive JPEG. If you need that, you'll need a WASM encoder.
β Your open source approach is cool β are you planning to keep it MIT?