🧲 gifgrep — Grep the GIF. Stick the landing.
gifgrep searches GIF providers and gives you two fast paths: scriptable CLI output for pipes, and an interactive TUI with inline previews.
TUI (animated inline previews)
|
CLI (pipeable output, optional still thumbs)
|
CLI • TUI • Stills (PNG) • Kitty previews
Website: https://gifgrep.com
Homebrew (recommended):
brew install steipete/tap/gifgrep
Go install:
go install github.com/steipete/gifgrep/cmd/gifgrep@latest
Features
- Scriptable search: readable plain output by default (TTY), plus
--format, --json, --max, --source.
- Inline thumbnails in search output:
--thumbs (Kitty/iTerm2/Sixel; TTY only; still frame).
- Download to
~/Downloads: --download (CLI), d (TUI). Reveal with --reveal (CLI/TUI) or f (TUI).
- TUI browser: inline preview, quick download, reveal last download.
- Stills:
still extracts one frame; sheet creates a PNG grid (--frames, --cols, --padding).
- Color + logging:
--color/--no-color, --quiet, --verbose.
- Providers:
auto (prefers Giphy when keyed, falls back to KLIPY), klipy, tenor (compatibility alias), giphy.
Quickstart
gifgrep cats --max 5
gifgrep cats --format url | head -n 5
gifgrep cats --download --max 1 --format url
gifgrep search --json cats | jq '.[0].url'
gifgrep tui "office handshake"
gifgrep still ./clip.gif --at 1.5s -o still.png
gifgrep sheet ./clip.gif --frames 9 --cols 3 -o sheet.png
Providers
Select via --source (search + TUI):
auto (default): tries Giphy when GIPHY_API_KEY is set, then falls back to KLIPY when KLIPY_API_KEY is set.
klipy: requires KLIPY_API_KEY.
tenor: backwards-compatible alias for Klipy, using KLIPY_API_KEY.
giphy: requires GIPHY_API_KEY.
CLI
gifgrep [global flags] <query...>
gifgrep search [flags] <query...>
gifgrep tui [flags] [<query...>]
gifgrep still <gif> --at <time> [-o <file>|-]
gifgrep sheet <gif> [--frames <N>] [--cols <N>] [--padding <px>] [-o <file>|-]
TUI vs CLI (and why previews differ)
- CLI: optimized for pipes. With
--thumbs, it shows a single still frame inline (first decoded frame).
- TUI: interactive browser. Inline previews are animated (full frame sequence).
- Inline previews work in terminals that support inline images:
- Kitty / Ghostty: Kitty graphics protocol.
- iTerm2: OSC 1337 inline images.
- Windows Terminal / WezTerm / Sixel-capable terminals: Sixel graphics.
- Truecolor terminals: ANSI half-block fallback (
GIFGREP_INLINE=ansi).
- Kitty: uploads the full animation (terminal plays it).
- Ghostty: software playback (gifgrep sends frames on a timer).
- Sixel: software playback (gifgrep redraws frames into the same cell area).
- ANSI: software playback (gifgrep redraws truecolor half-block frames).
How inline previews work (Kitty graphics protocol)
gifgrep decodes GIFs to PNG frames and streams them into the terminal via Kitty graphics escape sequences:
- Base64-encode PNG bytes and chunk them (4096 chars) into
ESC _G ... ESC \\ payloads.
a=T uploads the base image; a=f appends animation frames (with per-frame delay).
a=a sets animation timing / starts playback; a=p places the image in a cell rectangle.
- Old previews get cleaned up via
a=d (delete by image id).
iTerm2 inline images
iTerm2 uses a different protocol (OSC 1337). See docs/iterm.md.
Sixel inline images
Sixel-capable terminals use DEC Sixel graphics. See docs/sixel.md.
ANSI fallback
GIFGREP_INLINE=ansi renders GIF frames as truecolor half-blocks. It is lower
resolution than a bitmap protocol, but works in plain terminals that support
24-bit color.
JSON output
--json prints an array with: id, title, url, preview_url, tags, width, height.
Environment
KLIPY_API_KEY (required for --source klipy / --source tenor)
GIPHY_API_KEY (required for --source giphy)
auto uses Giphy first when keyed, then KLIPY if Giphy is unavailable.
GIFGREP_INLINE=kitty|iterm|sixel|ansi|none (override terminal detection)
GIFGREP_SOFTWARE_ANIM=1 (force software playback; default on Ghostty)
GIFGREP_CELL_ASPECT=0.5 (tweak preview cell geometry)
Test fixtures licensing
See docs/gif-sources.md.
Development
make test
make gifgrep GIFGREP_ARGS="--help"
make gifgrep -- --version
make gifgrep tui skynet
Ghostty web snapshot:
npm install
npx playwright install chromium
make snap
GitHub Pages
Landing page lives in docs/ (GitHub Pages -> main -> /docs).