Play GIFs in
your terminal.

One command. The GIF plays. gifterm exits. The animation lives on the GPU. No browser, no electron.

cargo install gifterm Copied!

Built for terminal natives.

GPU-native playback

Animations persist in kitty's GPU memory after gifterm exits. Like an <img> tag for your terminal. Clear the screen to dismiss.

Content-addressed cache

Frames are decoded once, cached by SHA-256 hash. Second play skips decode entirely. Width variants get their own cache key.

Fire and forget

gifterm exits immediately after transmitting frames. The animation loops on the GPU independently. Multiple GIFs run simultaneously.

Lanczos3 scaling

Pass --width 400 and gifterm scales with Lanczos3 filtering. Original aspect ratio preserved. Scaled frames cached separately.

Single static binary

Rust. No Python, no Node, no runtime dependencies. Compiles to one file you can drop on any machine.

Library + CLI

Import as a Rust crate without the CLI dependency. The library targets wasm32. Embed GIF playback in your own terminal tools.

Three steps, then gifterm gets out of the way.

Decode

GIF frames → raw RGBA buffers via the image crate. Optional Lanczos3 downscale.

Cache

Frames written to ~/.cache/gifterm/, keyed by SHA-256. Next time, decode is skipped.

Transmit

Frames sent via kitty graphics protocol. Terminal assembles a looping animation on the GPU.

// Library usage
use std::path::Path;

let path = Path::new("animation.gif");
let (meta, frames) = gifterm::load_frames(path, Some(400))?;
gifterm::play(&meta, &frames)?;

One command.

gifterm works with any terminal that supports the kitty graphics protocol.

$ cargo install gifterm
kitty
Full support
WezTerm
Full support
Konsole
Partial support

tmux blocks the graphics protocol by default. Set allow-passthrough on in your tmux.conf, or run gifterm in a raw terminal window.

Try it.