Skip to main content

anime-sh

Watch anime from your terminal.

Type a title. It finds a source, picks a mirror that works, and plays it in mpv.
Providers, mirrors and resolvers are plumbing you never have to think about.

PyPI Downloads Python CI Providers License: MIT

anime-sh running in Windows Terminal: Continue Watching with progress bars, Airing This Season, and a context panel showing the highlighted show's cover art, genres, progress and next episode

🚀 One line, from nothing

Both of these work on a machine with nothing on it. No Python, no administrator, no editing PATH by hand. mpv is installed alongside, because without it nothing plays.

Windows — paste into a normal PowerShell, not an administrator one:

irm https://raw.githubusercontent.com/Anime123450/anime-sh/master/install.ps1 | iex

macOS and Linux:

curl -LsSf https://raw.githubusercontent.com/Anime123450/anime-sh/master/install.sh | sh

Then run anime.

What those scripts do — and how to check one before you run it

Piping a script off the internet into your shell deserves a look first. Both take --dry-run, which prints every step and changes nothing:

irm https://raw.githubusercontent.com/Anime123450/anime-sh/master/install.ps1 -OutFile install.ps1
.\install.ps1 -DryRun
curl -LsSf https://raw.githubusercontent.com/Anime123450/anime-sh/master/install.sh -o install.sh
sh install.sh --dry-run

They are install.ps1 and install.sh in this repo, short enough to read in a minute.

On Windows it installs Scoop if you do not have it, adds the extras bucket (mpv lives there) and the anime-sh bucket, then installs anime-sh and mpv. Scoop is per-user, so nothing prompts for administrator and nothing is written outside your own profile.

On macOS and Linux it installs mpv with whatever package manager you already have — Homebrew, apt, dnf, pacman, zypper or apk — then installs uv and installs anime-sh with it. uv brings its own Python, so none needs to be on the system.

Both re-read PATH before finishing, so anime works in the window you ran them from rather than only the next one. Both are safe to run twice: a second run upgrades. Add -WithFfmpeg or --with-ffmpeg to also install ffmpeg, which only anime download needs.


📖 Contents

⚡ Install · 🔌 PATH · ▶️ A minute with it · 🎬 What you get · 🚀 First run · ⌨️ Keys · 🎨 Themes · 🔗 AniList · 📋 Commands · ⚙️ Config · 🩺 Troubleshooting · 🛠️ Develop


⚡ Install

Prefer to drive your own package manager? Each of these is live.

Channel Platform Brings mpv anime on PATH
🥄 Scoop Windows ✅ ✅ straight away
🍫 Chocolatey Windows ✅ ✅ after a new terminal
🍺 Homebrew macOS · Linux ✅ ✅ straight away
🐍 uv any ❌ ✅ via uv tool update-shell
📦 pipx any ❌ ✅ via pipx ensurepath
🐧 AUR Arch ✅ ✅ straight away
🧱 Single .exe Windows ❌ ❌ you pick where it lives

🥄 Scoop — the quickest route on Windows

# Skip these two if you already have Scoop.
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression

scoop bucket add extras
scoop bucket add anime-sh https://github.com/Anime123450/scoop-anime-sh
scoop install anime-sh

Use a normal PowerShell. Scoop installs per-user and refuses to run elevated.

The first line is what stops Windows refusing the second one with a message about running scripts being disabled. It applies to your account only, and RemoteSigned still requires downloaded scripts to be signed — it is what Microsoft ships on Windows Server. Answer Y when it asks.

The extras bucket is not optional. mpv lives there, a fresh Scoop has only main, and anime-sh declares mpv as a dependency — so without that bucket the install stops on something it cannot resolve.

Scoop's shims directory went on your PATH when you installed Scoop, so anime works immediately in the same window.

🍫 Chocolatey

choco install anime-sh

mpv comes with it. For downloads, choco install ffmpeg.

Chocolatey edits the machine PATH, which your current terminal read when it started. Open a new one.

🍺 Homebrew — macOS and Linux

brew tap Anime123450/anime-sh
brew install anime-sh

mpv comes with it. For downloads, brew install ffmpeg.

This builds from source, and takes the better part of an hour. On 0.2.85, CI measured Linux at 49 minutes; macOS ran past 40 and was still going. A tap carries no prebuilt bottles, so Homebrew compiles every dependency itself and two of them are slow — pydantic-core is Rust, Pillow is C. Upgrades reuse what is already built.

If that is unappealing, the one-liner at the top uses uv and finishes in seconds.

🐍 uv — any OS, no Python needed

uv is one standalone binary that brings its own Python, so this works on a machine with no Python at all.

# 1. uv, and mpv
curl -LsSf https://astral.sh/uv/install.sh | sh    # macOS / Linux
brew install mpv                                   # or apt / dnf / pacman

# 2. anime-sh
uv tool install "anime-sh[tui]"

# 3. put it on PATH, once
uv tool update-shell

On Windows the same thing, with winget install astral-sh.uv and winget install shinchiro.mpv for step 1.

Do not drop the [tui]. Without it anime still installs and anime --version still answers, so a missing extra is easy to miss until the interface refuses to start.

uv tool update-shell edits the right profile for your shell. Open a new terminal afterwards, or export PATH="$HOME/.local/bin:$PATH" for this one.

📦 pipx

pipx install "anime-sh[tui]"
pipx ensurepath

pipx is itself a Python package, so it cannot be the first thing installed on a clean machine. Already have it? Then this is fine.

🐧 Arch

yay -S anime-sh    # or: paru -S anime-sh
Other ways in — one file, no terminal, or from source

Just the executable. Every release carries anime-sh-<version>-windows-x64.exe, about 21 MB with Python and every library inside it. Download it and run it; there is no install step. You still need mpv on your PATH, and since you chose where the .exe lives, putting that on PATH is yours to do as well.

No terminal at all. Download this repo as a ZIP, unzip, double-click run-anime.bat. It installs what is missing and starts the app.

From source:

git clone https://github.com/Anime123450/anime-sh.git && cd anime-sh
uv sync --extra tui
uv run anime

🔌 Will anime be on my PATH?

Yes, with every method except the bare .exe. The longer answer earns its space, because "command not found straight after installing" is the most common thing people hit and it is almost never a broken install.

Why it happens. A program is found by searching the directories in PATH. An installer adds its directory to the stored PATH, but a terminal reads that value once, when it opens. Your terminal is still holding the old copy. The install worked. The window has not heard about it.

Installed with What to do
One-line installer Nothing. Both scripts re-read PATH before finishing.
Scoop Nothing. The shims directory went on PATH with Scoop itself.
Chocolatey Open a new terminal.
Homebrew Nothing, as long as brew works in that shell.
uv uv tool update-shell once, then a new terminal.
pipx pipx ensurepath once, then a new terminal.
Bare .exe Add its folder to PATH, or run it by full path.

Repair the window you already have, without restarting it:

# Windows
$env:Path = [Environment]::GetEnvironmentVariable('Path','Machine') + ';' +
            [Environment]::GetEnvironmentVariable('Path','User')
# macOS / Linux
export PATH="$HOME/.local/bin:$PATH"

Two copies? Install with two managers and anime exists twice, with PATH order quietly deciding which runs — so upgrading one can look like it did nothing at all. where.exe anime on Windows, which -a anime on Unix, lists every match. The Windows one-line installer warns about this rather than silently adding a second.

What you need alongside it

Why Required?
🎥 mpv plays the video yes — every package manager above brings it
✂️ ffmpeg saves downloads only for anime download
🐍 Python 3.11+ runs the app only for the uv, pipx and source installs

anime doctor checks all of them and prints the exact command for whichever package manager you actually have. anime doctor --streams goes further and plays something through each provider from your own connection, which answers "is it broken, or is it me?"


▶️ A minute with it

anime-sh in use: the home screen with Continue Watching, typing a search, a show's episodes as a grid, and the same episodes as a list

Home · search-as-you-type · a show's episodes, in two of the three layouts

Every frame is the real application, rendered and captured from the app itself. Not a mockup of it.


🎬 What you get

🔎 Forgiving search atack on titan, dont toy with me — it finds them anyway
🎥 Plays in mpv driven over JSON IPC, and your own mpv config still applies
⏭️ Skips intros and outros then rolls straight into the next episode
📚 Remembers everything resume position, history and favourites, in a local database
🔄 AniList two-way sync finish an episode here and your phone knows
🧩 Multiple providers fanned out behind circuit breakers, so one site dying is not an outage
🖼️ Cover art in the terminal unicode block sextants, sharper again on Sixel or kitty
🎨 Nine themes previewed live as you arrow through them
🧱 Layouts that fit you episodes as a grid, a list or compact; two home densities
⬇️ Downloads ffmpeg-backed, resumable, played back offline automatically
🎒 Stocks up before you ask prefetch saves the next episode of everything you are watching
📊 Your year, wrapped streaks, top shows and busiest day, as a shareable SVG card
🔌 Plugin providers a provider is an entry point, so adding one needs no fork

🚀 First run

anime            # the TUI: Continue Watching, Airing This Season, Trending

The right-hand panel follows your cursor: poster, what the show is, how far into the episode you got, when the next one airs, and what Enter will do. Under it sits everything you are waiting on, grouped by day.

Prefer one-shot commands? anime "Frieren" searches, takes the best match and plays episode 1. anime play "Frieren" -e 18 --dub -q 1080p spells it all out.

Shell tab-completion is one command: anime --install-completion.


⌨️ Keys

Key Does
🕹️ ↑ ↓ / j k move within a list
⤒ g / G first / last row
↹ Tab / Shift+Tab next / previous section
▶️ Enter open a show, or play the highlighted episode
🔎 / search
↩️ Esc clear the search, or go back
📺 l your AniList list
🎨 t theme picker
🧩 p providers — which sources get searched
🧱 v view — home density, or episode layout on a show
⏭️ n next season, on a show
❓ ? every key, any time
🚪 q quit

🎨 Themes

Press t. Moving the cursor applies each theme to the whole app at once, so you choose by looking at anime-sh rather than at a list of names. Enter keeps it, Esc restores the one you arrived with.

Three are anime-sh's own — midnight (the default), ember and paper — next to tokyo-night, nord, gruvbox, dracula, catppuccin-mocha and solarized-light.

The context panel: a show's cover art above its title, format, genres, progress bar, next episode countdown, synopsis, and the action Enter will take

Cover art is drawn with unicode block sextants, so no special terminal is required. On Sixel or kitty terminals it sharpens automatically.


🔗 Linking AniList (optional)

Everything works without an account. Linking one adds two-way sync: finish an episode here and your phone knows, and anime sync pull brings in whatever you have been watching elsewhere.

anime-sh ships no API credentials, and there is no shared app to sign in through. You create your own client. It takes about a minute, and it means the token belongs to you:

  1. Open AniList → Settings → Developer and create a client.
  2. Name: anything. Redirect URL: https://anilist.co/api/v2/oauth/pin
  3. Link it:
anime auth login --client-id <YOUR_ID> --secret <YOUR_SECRET>

The token is written to your own config directory with 0600 permissions, goes nowhere but AniList, and anime auth logout deletes it. Nothing about your account is stored in this project.


📋 Command reference

Every command — watch, discover, library, downloads, housekeeping
# ▶️  Watch
anime                          # the TUI
anime "Frieren"                # search, best match, play episode 1
anime play "Frieren" -e 18     # a specific episode
anime play "Frieren" --dub -q 1080p
anime resume                   # pick up the show you watched most recently
anime continue                 # what to watch next in every show you have going
anime sources "Frieren"        # every provider entry that matches
anime next "Frieren"           # find and play the sequel

# 🔭  Discover
anime search "frieren"         # AniList search, no providers touched
anime trending
anime seasonal                 # defaults to the current season
anime calendar                 # what is airing, and when
anime random
anime recommend "Frieren"
anime related "Frieren"

# 📚  Library and tracking
anime history
anime stats                    # episodes, hours, top providers and genres
anime wrapped                  # your year, with a shareable SVG card
anime favorite add "Frieren"
anime favorite list
anime unmark "Frieren"         # clear local progress for a show

# 🔗  AniList
anime auth login --client-id <ID> --secret <SECRET>
anime auth logout
anime list --status watching
anime rate "Frieren" 9
anime status "Frieren" completed
anime sync push                # local progress  ->  AniList
anime sync pull                # AniList  ->  local library

# ⬇️  Downloads
anime download "Frieren" -e 1-12
anime downloads                # what is already on disk
anime prefetch                 # next episode of everything you are watching

# 🎨  Appearance
anime themes

# 🧹  Housekeeping
anime doctor                   # player, ffmpeg, cover art, config, database, plugins
anime doctor --streams         # actually play through each provider
anime providers health         # circuit-breaker state per provider
anime config get ui.theme
anime config set ui.theme ember
anime --install-completion

⚙️ Config

anime config set <section>.<key> <value> writes one; anime config get reads it back. Only keys you set are stored, so defaults can keep improving without your file pinning them in place.

Section Keys
player name, args
playback quality, audio, auto_next, skip_intro, skip_outro, prefer_downloads
providers parallel, preferred, disabled, timeout_s, match_timeout_s, hianime_base
resolvers disabled
ui theme, episodes, density
downloads dir
anime config set playback.audio dub
anime config set playback.quality 1080p
anime config set ui.episodes grid
anime config set downloads.dir ~/Videos/anime

Any of them can be set by environment variable instead, which is the easier route for one-off runs and for scripts that should not touch your config file. The name is ANIME_SH_, the section, two underscores, then the key — and it wins over the file for that one setting, leaving the rest of your config alone.

ANIME_SH_PLAYBACK__AUDIO=dub anime play "Frieren"
ANIME_SH_UI__THEME=nord anime

When more than one of them sets the same thing, the winner is, highest first: a flag on the command line, an environment variable, your config file, the built-in default.


🩺 Troubleshooting

Symptom What is going on
🤔 anime not recognised right after installing The install worked; your shell has a stale PATH. See PATH.
🎥 doctor says mpv not found Nothing plays without it. doctor prints the right command for your package manager, or use scoop install mpv / brew install mpv / choco install mpvio.
🧊 A show will not play Plain anime doctor now carries a provider health line reading what the circuit breaker already learned on previous runs — it names any provider that is open or half-open and how many failures got it there, without touching the network. anime doctor --streams goes further and actually plays through each provider from your connection. A dead provider is normal and the fan-out routes past it; anime providers health shows the full counts.
🔇 Dub not playing anime config set playback.audio dub, or pass --dub per run. Not every provider carries one.
🐍 pipx or pip "not recognised" The wrong starting point on a clean machine — both are Python packages. Use the one-liner at the top, or scoop/choco.
🖼️ Cover art looks blocky anime doctor — run on its own, not piped — says which renderer the TUI will use. unicode blocks with no complaint beside it means your terminal reported no Sixel or kitty graphics, and that fallback is doing its job. A ✗ saying textual-image did not record a finished capability probe means a bitmap was refused rather than drawn: reinstall with uv tool install --force "anime-sh[tui]", and report the line if it survives that. true bitmap alongside a blocky poster is a bug worth reporting. ANIME_SH_NO_GRAPHICS=1 forces the blocks.
🧵 Cover art is sharp but slightly soft doctor also prints the character-cell size posters are scaled against. Posters are scaled to that size, so a wrong one has the terminal resampling the image. 10×20px is the only reading that is ambiguous — it is both a real answer (Windows Terminal replies exactly that) and textual-image's fallback when nothing replies. If your cells are not that size, set TEXTUAL_CELL_WIDTH and TEXTUAL_CELL_HEIGHT to the real one.
📺 Two anime commands Installed with two managers. where.exe anime or which -a anime finds both; remove the one you do not want.

🛠️ Develop

git clone https://github.com/Anime123450/anime-sh.git && cd anime-sh
uv sync --extra dev --extra tui
uv run pytest -q          # the full suite
uv run lint-imports       # layering contracts
uv run anime

The architecture is layered, and the layering is enforced rather than aspirational: cli > tui > app > domain, with infra, providers and resolvers as adapters. uv run lint-imports fails the build when a layer reaches somewhere it should not.

Providers and resolvers are found through entry points (anime_sh.providers, anime_sh.resolvers), so a new one is just a package that declares one.

A nightly canary plays a real episode through every provider and opens an issue when one breaks. It fails the run only when nothing can play, because a single provider dying is the normal operating state here, and an alert that fires every night is one nobody reads.

📄 Architecture · Writing a plugin · Engineering standards · Contributing · Packaging

The engineering standards are worth a read even if you never contribute — every rule names the bug that caused it.


anime-sh is a client, not a content library. It bundles no media, mirrors nothing, and bypasses no DRM. Providers read public pages and are expected to break; a broken provider is a degraded experience rather than an outage, and provider plugins are separable from the core, so the project outlives any one of them.

mpv and ffmpeg are declared as dependencies and never redistributed. Both are GPL-licensed, and shipping their binaries inside an MIT release would carry obligations that depending on them does not.

Not affiliated with AniList, mpv, or any provider.


Metadata

Release files for anime-sh 0.2.89

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for anime-sh 0.2.89
File Size Uploaded
anime_sh-0.2.89.tar.gz 218.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for anime-sh 0.2.89
File Interpreter ABI Platform
anime_sh-0.2.89-py3-none-any.whl Python 3 none any Details

Total release size: 479.3 kB

Release files / anime_sh-0.2.89.tar.gz

Download URL anime_sh-0.2.89.tar.gz
Size 218.2 kB
Tags Source
SHA-256 checksum
How to use checksums
fce3cbd23fe59ec52c02913f1783855e7705adba482f87ddde440afb9231e6a2
BLAKE2b-256 checksum
How to use checksums
a66e37f4c01187612109f3d541f6814e9cc3381ba146d49c101cbee14e0f7d90
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / anime_sh-0.2.89-py3-none-any.whl

Download URL anime_sh-0.2.89-py3-none-any.whl
Size 261.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a71c09bce59c082ae1e6487f07c9b57cce178e4b42cb6dba6c62a1f09b772c32
BLAKE2b-256 checksum
How to use checksums
2fd1c6e256eb7c028159d27a8b2424f8aa5e4df198f3a4a87fd3f42035b14623
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.89 This release

2 release files

0.2.84

2 release files

0.2.83

2 release files

0.2.82

2 release files

0.2.81

2 release files

0.2.68

2 release files

0.2.67

2 release files

0.2.66

2 release files

0.2.65

2 release files

0.2.64

2 release files

0.2.63

2 release files

0.2.61

2 release files

0.2.60

2 release files

0.2.59

2 release files

0.2.58

2 release files

0.2.57

2 release files

0.2.56

2 release files

0.2.55

2 release files

0.2.54

2 release files

0.2.53

2 release files

0.2.52

2 release files

0.2.51

2 release files

0.2.50

2 release files

0.2.49

2 release files

0.2.48

2 release files

0.2.47

2 release files

0.2.46

2 release files

0.2.45

2 release files

0.2.44

2 release files

0.2.43

2 release files

0.2.34

2 release files

0.2.33

2 release files

0.2.32

2 release files

0.2.31

2 release files

0.2.30

2 release files

0.2.29

2 release files

0.2.28

2 release files

0.2.27

2 release files

0.2.26

2 release files

0.2.25

2 release files

0.2.24

2 release files

0.2.23

2 release files

0.2.22

2 release files

0.2.21

2 release files

0.2.20

2 release files

0.2.19

2 release files

0.2.18

2 release files

0.2.17

2 release files

0.2.16

2 release files

0.2.15

2 release files

0.2.14

2 release files

0.2.13

2 release files

0.2.12

2 release files

0.2.11

2 release files

0.2.10

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page