I kept using online file compressors and realized they all upload your files to sketchy servers. For tax PDFs, personal photos, and sensitive documents β that didn't feel right.
So I built ShrinkRay β a file compressor that runs entirely in your browser. No backend, no uploads, no sign-up.
Try it: https://shrink-ray.vercel.app
Source: GitHub
What it compresses
Images: PNG, JPEG, WebP, AVIF, HEIC (iPhone photos), GIF, BMP
Video: MP4, WebM, MOV, MKV, animated GIF (via ffmpeg.wasm)
Audio: MP3, WAV, OGG, M4A, FLAC, OPUS
PDF: Re-renders pages as compressed images
3D Models: GLB, GLTF, STL, OBJ, PLY, FBX β with format conversion via Three.js
SVG: Minification (strips metadata, comments, whitespace)
Text/Code: JSON, HTML, CSS, JS, XML, YAML β minified + gzipped
Anything else: Gzip compression
How it works
File type
Engine
How
Video ffmpeg.wasm Compiled to WebAssembly, runs in-browser
Images Canvas API + OffscreenCanvas Re-encode at chosen quality/format
Audio Web Audio API + lamejs Decode β re-encode to MP3
PDF pdf-lib + pdfjs-dist Render pages β rebuild with compressed images
3D Three.js Format conversion (STLβGLB, etc.) + gzip
Text/Code Native JS + fflate Minify (strip comments/whitespace) β gzip
The architecture
Zero backend. It's a static site hosted on Vercel. There is no server β your files are processed entirely in the browser using WebAssembly and Canvas APIs.
text
Browser (your device)
βββ Drop file
βββ Auto-detect type (image/video/audio/pdf/3d/text)
βββ Route to correct engine
βββ Process entirely in memory (Blob URLs)
βββ Download result
β³ Files NEVER touch a server
Key technical decisions
- Lazy-loaded heavy dependencies
ffmpeg.wasm is 32MB. We don't load it until you actually drop a video. Same for Three.js (3D), heic2any (HEIC photos), and pdfjs (PDFs). Initial page load stays fast.
- Multi-threaded ffmpeg when available
On browsers with SharedArrayBuffer (COOP/COEP headers), ffmpeg uses multiple CPU cores via Web Workers. Falls back to single-threaded automatically.
- Pre-warm on desktop, skip on mobile
On desktop, ffmpeg starts loading the moment the page opens (so it's ready when you drop a video). On mobile, we skip this β the 32MB download would freeze low-RAM devices.
- Never return a larger file
If compression makes a file bigger (happens with already-compressed files), we return the original instead. You never download a file larger than what you uploaded.
- Mobile memory safeguards
Mobile devices get stricter file size limits (100MB for video vs 500MB on desktop), and ffmpeg is terminated after each conversion to free memory.
The privacy model
This is the whole point:
100% client-side β files are processed in your browser
Zero network requests during compression
No accounts, no tracking, no analytics, no cookies
No server-side storage β there IS no server
Open source β read every line of code
Your files are yours. They shouldn't need to visit a server to be compressed.
Try it
Live: https://shrink-ray.vercel.app
Source: https://github.com/JeffreyHamilton6399/ShrinkRay
Feedback welcome β happy to answer questions about the ffmpeg.wasm setup, the 3D conversion pipeline, or the architecture.











