DEV Community

Calvin
Calvin

Posted on Originally published at omnigif.com

Building OmniGIF: A Client-Side GIF Toolkit with WebAssembly (No Server Uploads)

Most online GIF tools send your file to a remote server. I built OmniGIF to prove that's unnecessary — modern browsers can decode, encode, and transform GIFs entirely on the client.

The architecture problem

Traditional flow:

User → Upload to server → Process → Download result
Enter fullscreen mode Exit fullscreen mode

OmniGIF flow:

User → Load page → Process in browser (JS + WASM) → Download result
Enter fullscreen mode Exit fullscreen mode

The file never hits our infrastructure. From a privacy and latency perspective, this changes the product entirely.

Tech stack

Layer Choice
Framework Next.js 15 (SSG)
Language TypeScript
Styling Tailwind CSS 4
i18n next-intl (EN + ZH)
Hosting Cloudflare (OpenNext)
Analytics PostHog

The site is statically generated. There's no server-side file processing — which is intentional.

Client-side libraries

GIF work on the web is surprisingly mature. OmniGIF relies on:

  • gifuct-js — GIF89a decoder; parses frames and delay metadata locally
  • gif.js — GIF encoder running in a Web Worker
  • ffmpeg.wasm — FFmpeg compiled to WebAssembly for Live Photo / video → GIF
  • UPNG.js — PNG/APNG encode/decode for high-color animated workflows
  • gifsicle-wasm-browser — GIF optimization in the browser
  • JSZip — bundling extracted frames into ZIP downloads

Per MDN's WebAssembly docs, Wasm brings near-native performance to the web — which matters when you're encoding 30 frames at 1080p.

What the toolkit includes

31 tools across four categories:

GIF Converter

GIF Tools

Frame inspection, crop, trim, reverse, compress, compress to target size, text/watermark overlay, GIF overlay, watermark removal.

GIF Maker

Intensify, shake, fire text, vinyl spin.

GIF Effects

B&W, border, confetti, dither (Floyd–Steinberg, Bayer, Atkinson), pixelate, fade, speed, glitch.

Full list: llms.txt (machine-readable sitemap for tools).

Design decisions

Why SSG, not SSR?

All parameters are client-side. No need for server rendering of user files. Faster cold loads, simpler deployment on Cloudflare.

Why Web Workers?

GIF encoding blocks the main thread. gif.js and heavy transforms run off-thread so the UI stays responsive.

Why per-tool pages instead of one mega-app?

SEO, shareability, and focused UX. Each tool has its own URL, metadata, FAQ, and structured data. Users land on exactly what they need.

Real-time preview on desktop

For tools with tunable parameters (crop, effects, compression), the right panel shows a live preview on PC. Mobile gets before/after after generation — saves battery and screen space.

Chrome extension

The OmniGIF extension bridges web → tool: right-click any image, pick a destination tool, and the image is passed via URL params / clipboard. Offline install package available for environments that need it.

Challenges

  1. Memory — Large GIFs (many frames × high resolution) can OOM on mobile. We enforce file size limits and warn early.
  2. GIF color depth — GIF is 256 colors max. Converting from APNG/PNG requires palette reduction; dithering quality varies by algorithm.
  3. ffmpeg.wasm bundle size — First load downloads a sizable Wasm binary. Lazy-loading FFmpeg only on video tools helps.
  4. Cross-browser APNG — APNG support is uneven; we document browser compatibility on converter pages.

Privacy as a feature, not a footnote

The W3C GIF89a spec hasn't changed much in decades, but how we process GIFs can change. Client-side tooling means:

  • No file retention policies to worry about
  • No GDPR data-transfer questions for the image itself
  • Works offline after first page load (extension + cached assets)

Try it / feedback

Live at https://www.omnigif.com — free, no account.

More background: About OmniGIF

Questions: FAQ | Contact

Built by Calvin Sun as an indie project. Feedback welcome.

Top comments (0)