Most online GIF makers upload your video to a server, add a watermark, and bury the download button under ads. I wanted the opposite, so I built Snipgif: a free, open-source video-to-GIF converter where your file never leaves your device.
What it does
- Convert MP4, MOV, WebM, or AVI to GIF
- Trim on a timeline (up to 30 seconds of GIF)
- Presets (Small for chat, Balanced, High quality) or custom FPS, width, and quality
- Crop to 1:1, 16:9, or 9:16, change speed, reverse, or boomerang
- Meme-style captions
- A standalone GIF compressor (fewer colors, skipped frames, smaller width)
- Installable as an app, and it works offline
How it works
The whole conversion runs in the browser with ffmpeg.wasm. The site itself is a static Astro build. Only the converter and compressor are React islands, so the other pages ship almost no JavaScript.
A few decisions that mattered:
1. Load the 30 MB engine only when needed. The ffmpeg core is big. It isn't part of the page load. It downloads from jsDelivr the moment you pick a file, so by the time you hit Convert it's usually ready.
2. Single-threaded core on purpose. The multi-threaded ffmpeg.wasm core needs SharedArrayBuffer, which means COOP/COEP headers. Those headers block third-party resources that don't opt in. The single-threaded core is slower, but it keeps hosting simple.
3. Offline with a hand-written service worker. At build time, a small Astro integration writes the full list of built files into sw.js, so every page is cached on install. The ffmpeg core is cached the first time you use it.
One bug worth sharing: my first version did await cache.put(...) before returning the response. If the browser refused to store the 30 MB file (a phone low on storage, for example), a successful download turned into an error. The fix was to make caching best-effort: return the response right away and do the cache write in event.waitUntil(...), swallowing errors. A cache should make things faster, never break them.
4. Privacy without a cookie banner. Analytics are optional (GA4). Google Consent Mode defaults to denied for visitors in the EEA, the UK, and Switzerland, so they get no analytics cookies and no banner is needed.
Stack
Astro, React, TypeScript, Tailwind CSS, shadcn/ui, ffmpeg.wasm, deployed on Vercel.
Try it or contribute
- Live: https://snipgif.vercel.app
- Code (MIT): https://github.com/saidMounaim/snipgif
Issues and pull requests are welcome. I'd love feedback, especially on performance with large videos on mobile.
Top comments (0)