No description
  • TypeScript 96.9%
  • CSS 3.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-07-24 11:06:16 -04:00
.zed initial commit 2026-07-23 14:16:55 -04:00
public self-host multithreaded ffmpeg assets 2026-07-24 10:59:30 -04:00
src use single-thread ffmpeg in development 2026-07-24 11:06:16 -04:00
.cta.json initial commit 2026-07-23 14:16:55 -04:00
.gitignore initial commit 2026-07-23 14:16:55 -04:00
.oxfmtrc.json initial commit 2026-07-23 14:16:55 -04:00
bun.lock proxy ffmpeg assets with isolation headers 2026-07-24 11:00:58 -04:00
package.json proxy ffmpeg assets with isolation headers 2026-07-24 11:00:58 -04:00
README.md initial commit 2026-07-23 14:16:55 -04:00
tsconfig.json initial commit 2026-07-23 14:16:55 -04:00
tsr.config.json initial commit 2026-07-23 14:16:55 -04:00
vite.config.ts initial commit 2026-07-23 14:16:55 -04:00
worker-configuration.d.ts initial commit 2026-07-23 14:16:55 -04:00
wrangler.jsonc route / tweak 2026-07-23 14:34:03 -04:00

gifslop

A small TanStack Start app that converts MOV/MP4 videos to GIFs entirely in the browser with ffmpeg.wasm.

Why client-side?

For a small, occasional-use app this is the simplest and most private architecture:

  • video bytes never leave the device
  • no upload storage, job queue, or FFmpeg server to operate
  • static/serverless-friendly deployment
  • the FFmpeg core is loaded only when conversion starts

The tradeoffs are the initial WebAssembly download, browser memory limits, and slower conversion than native FFmpeg. A native server worker becomes worthwhile for long videos, files above a few hundred MB, batch processing, or many regular users.

Develop

bun install
bun --bun run dev

Code quality

The project uses the Oxc toolchain:

bun run format
bun run lint
bun run typecheck
bun run check

Deploy to Cloudflare Workers

The app uses Cloudflare's official Vite plugin with TanStack Start's Worker entrypoint.

bunx wrangler login
bun run deploy

Generate binding types after adding Cloudflare bindings to wrangler.jsonc:

bun run cf-typegen

Equivalent native FFmpeg command

The default settings reproduce the command previously used for the full video:

ffmpeg -y -i input.mov \
  -vf "fps=24,scale=240:-1:flags=lanczos,split[s0][s1];[s0]palettegen=max_colors=64[p];[s1][p]paletteuse=dither=bayer" \
  -loop 0 output.gif