Back to articles index
How-to guides

How to convert a video clip into an animated GIF

Turn an MP4 or WebM into a looping GIF. Explains how frame rate, resolution, and palette size trade against file size, all converted locally with ffmpeg.wasm.

Where GIFs still earn their keep

MP4 and WebM have won the general video war, but GIF refuses to retire from a surprising number of corners. GitHub Issue and Pull Request bodies render animated GIFs inline but treat MP4 attachments as plain download links. Slack and Discord auto-loop GIFs in the message stream the way they used to. Documentation surfaces (Notion, internal wikis, READMEs) often embed short interaction demos as GIFs because the editor only supports image embeds. In all these places you end up converting from MP4 back to GIF whether you like it or not.

The numbers explain the friction. A 10-second screen recording from macOS’s built-in screen capture, Cleanshot, or Loom is typically 2–3 MB as MP4 — but the same clip will balloon to 8–15 MB as a GIF if you accept whatever defaults the converter hands you. Get sloppy and you cross 30 MB, which Slack will refuse to preview and GitHub will reject on drag-and-drop. With deliberate settings you can land in the 1–3 MB range, but that means consciously knocking down fps and width, and that workflow is exactly what the in-browser video-to-gif optimises for.

Doing the conversion in the browser

Open the video-to-GIF tool and drop your clips. It accepts MP4, MOV, WebM, MKV, AVI, and other common containers, and you can convert several files in one batch. After load, two sliders appear — fps (1–60) and width px (64–4096) — along with start / end inputs (in mm:ss or seconds) so you can trim out only the segment you actually need.

A safe starting point is 10 fps / 480 px. Going from 24 fps down to 10 fps roughly halves the frame count, and at the small embed sizes used inside Slack or Notion the motion still reads fine. Setting the width to 480 px and letting the tool keep the aspect ratio for the height typically cuts the pixel count to about a third of a screen capture, which is a big lever on file size. Press Convert to GIF and the embedded ffmpeg.wasm starts encoding; once a file is ready you get a per-file Download button plus a Download ZIP control for the whole batch.

palettegen and paletteuse, the two-pass trick

GIF is a late-1980s format and it has hard limits — each frame uses an 8-bit palette, meaning at most 256 distinct colours per frame. Convert a video naively and any gradient, skin tone, or sky region falls apart into ugly banding. ffmpeg handles this with a two-pass workflow: palettegen scans the input to build an optimised 256-colour palette tuned for the actual content, then paletteuse re-encodes the frames against that palette with a configurable dithering algorithm. video-to-gif runs that same two-pass internally, which is why the result looks noticeably better than a single-pass GIF converter.

The dominant terms in the final file size are frame count (fps × duration) and resolution (width × height). GIF’s LZW compression helps at the margins but cannot rescue a wasteful frame budget. A 480 px / 10 fps / 5 s clip ends up roughly 1/12 the size of the same content at 960 px / 30 fps / 5 s. “The quality is bad, let me raise the fps” almost never works — dropping fps and width by one step and trimming to the exact segment you want produces a smaller and cleaner result. If your real goal is high-motion playback for a social post and not the GIF format itself, the opposite direction makes more sense: encode to MP4. The companion gif-to-mp4 shrinks animated GIFs to H.264 MP4 at roughly 1/5–1/10 the size, which is what platforms like X (Twitter), Bluesky, and Discord prefer for inline autoplay.

What changes versus an upload-style converter

A search for “video to GIF online” surfaces dozens of sites that take your upload and email back a download link. The catch is what you are shipping over the wire — for a screen recording it is the contents of your editor (unreleased code, customer data); for a product demo it is internal dashboards; for a rehearsal it is unannounced slides. The terms of service usually say something like “files are deleted after one hour”, but you have no external way to confirm that, and the CDN caches and access logs in between are out of your audit reach.

video-to-gif loads ffmpeg.wasm into a Web Worker, runs the palettegen → paletteuse pipeline against the input bytes in the Worker’s memory, and exposes the final GIF as a Blob behind an <a download> element. There is no upload code path in the source. The repository is public on GitHub, so you can audit the conversion code directly, and keeping the DevTools Network tab open during a run shows nothing tied to the video content leaving after the initial WASM fetch.