The whole loop, one client
Browse, watch, track, sync, extend — a complete platform, not a wrapper around one website. Every volatile piece sits behind a trait, so the client outlives any single source.
Browse without an account
Search, seasonal charts and an airing calendar ruled by day — today, tomorrow, the week — from AniList’s public API. Watch order untangles prequels and sequels in place. No login, no config — browsing is the default state of the app.
mpv does the playing
JSON IPC to real mpv: resume to the second, auto-next, persisted speed and volume, and Shift+N/P step episodes from inside the player itself. Opening-skip prefers the file’s own chapter markers and falls back to aniskip. Anime4K upscaling ships inside the binary — a config toggle, not a shader hunt. Licensed services open in their own apps, by deep link.
Watch parties, one key deep
Press y and the episode you were about to play opens in a Syncplay room instead — same resolution, shared pacing, everyone’s player in step. A party is a handoff, deliberately: the room’s pauses are not your watch history.
Every pick explains itself
Automatic selection is ranked, curated against SeaDex where it has an opinion, and says why in one line. Disagree? One key lists the whole slate — seeders, size, audio — and your choice is exact, with no failover behind it. Sub or dub preference picks the audio and subtitle tracks too, never file order.
Local is the source of truth
History is SQLite on your disk and works with no account at all. Sync is a projection of it — never the other way around.
Sync that survives being offline
AniList, MyAnimeList, Simkl and Trakt through a durable outbox. Watch offline for a week; it pushes in order when you return. Real conflicts get a screen, not a silent overwrite.
Bring your own sources, as plugins
Provider plugins are sandboxed WASM components in Rust, Go, JavaScript or Python — built for legitimate APIs, self-hosted services, and your own media. The sandbox has no sockets; the host lends fetch, so a plugin is kilobytes and cannot exfiltrate.
Real images, in the terminal
Cover art renders as actual images over the Kitty, Sixel and iTerm2 protocols, decoded off the event loop so scrolling never stutters. Elsewhere it falls back to halfblocks, and says so.
If you torrent, it fails closed
Torrent support exists, and it is never assumed: off by default, unreachable until a VPN mode is chosen and egress is verified through the proxy. DHT forced off, re-checked on an interval, every transfer paused the moment a check fails — and seeding stops when a download completes, unless you opt in.
Downloads that behave like a library
Queue one episode or a typed range, watch it with full history and resume like any stream, and let a post-download hook hand finished files to whatever comes next. Subtitles mux in, files land where you said, deletion is one explicit key.
Vim-first, fully rebindable
hjkl everywhere, arrows always aliased, every key rebindable. The help overlay is generated from the resolved keymap, so it matches whatever you set. Filler filters, watched marks and range downloads are each a single key away.
Legal sources first. External, always.
anistream hosts no content and ships no sources of its own.The intended path is legitimate: AniList’s public API for browsing, deep links that open licensed services in their own apps — never scraped, never DRM-circumvented — and plugins for APIs you have the right to use, self-hosted servers, and your own media. Torrent support exists too, off by default and unreachable without the VPN guard; what you point any external source at is your decision, at your own risk, under the laws that apply to you. Every source is a config edit away from being removed.
Prebuilt, or from source
Binaries for macOS, Linux and Windows are on thereleases page, or build it yourself from the code. Either way you need mpv and ffmpeg installed — neither is bundled. Browsing works immediately, with no account and no config.
$ brew install mpv ffmpeg # mpv plays, ffmpeg muxes subtitles # grab the installer or archive for your platform from the releases page, # then staying current is one command: $ anistream --update # verified against the published sha256
best in a terminal with a graphics protocol · ghostty · kitty · iterm2 · wezterm
Building in the open
anistream is under active development. Kitsu sync is still to come, and the plugin system is the path for new sources. Follow along, open an issue, or write a provider plugin: the architecture was built for other people’s ideas to plug into.
流 NAGARE — anistream’s mascot.
an original character; appears wherever anistream goes.