$ anistream

An anime streaming TUI.

The whole loop in one client — browse, watch, track, sync, extend. Written in Rust, played by mpv, lives in your terminal.

cover — rendered as halfblocks · 屋上の夜
── features

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

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.

▶ playback

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.

▞ together

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.

⌕ chosen

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-first

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

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.

▢ plugins

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.

▚ graphics

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.

● guarded

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.

↓ offline

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.

? keys

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.

◇ sources

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.

↓ install

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

▸ next

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.