Jellyfin-tui is a (music) streaming client for the Jellyfin media server. Inspired by CMUS and others, its goal is to offer a self-hosted, terminal music player with all the modern features you need.
Ctrl+Up/Down
Pre-built binaries for Linux and macOS are available on
the releases page.
Download the binary for your platform, make it executable, and place it somewhere on your PATH.
jellyfin-tui is available as a package in the AUR. You can install it with your preferred AUR helper. Example:
paru -S jellyfin-tui
jellyfin-tui is available as a package in Nixpkgs.
jellyfin-tui is available as a package in the Alpine Linux community repository.
Jellyfin-tui depends on libmpv2 (audio playback) and sqlite3 (offline caching), both of which should be
available in your distribution's package manager. On Debian/Ubuntu based systems, you may need to install libmpv-dev
and libssl-dev as well for building.
# If you're new to rust:
# install rust from https://rustup.rs and make sure ~/.cargo/bin is in your PATH (add this to ~/.bashrc or ~/.zshrc etc.)
export PATH=$PATH:~/.cargo/bin/
# Arch
sudo pacman -S mpv sqlite
# Ubuntu/Debian
sudo apt install mpv libmpv-dev sqlite3 libssl-dev
# clone this repository
git clone https://github.com/dhonus/jellyfin-tui
cd jellyfin-tui
# optional: use latest tag
git fetch --tags
git checkout $(git tag | sort -V | tail -1)
cargo install --path .
brew install mpv
git clone https://github.com/dhonus/jellyfin-tui
cd jellyfin-tui
# add exports to your shell profile (~/.zshrc etc.)
export LIBRARY_PATH="$LIBRARY_PATH:$(brew --prefix)/lib"
export PATH=$PATH:~/.cargo/bin/
cargo install --path .
When you run jellyfin-tui for the first time, it will guide you through creating a configuration file. You can authenticate using either username/password, password file, or jellyfin quick connect. Each of these options then uses locally stored auth tokens for future logins.
The program prints the config location when run. On linux, the configuration file is located at
~/.config/jellyfin-tui/config.yaml. Feel free to edit it manually if needed.
servers:
- name: Password Server
url: 'https://jellyfin.example.com'
username: 'username'
password: 'imcool123'
default: true # Add to skip server picker on startup. Use --select-server to override
- name: Quick Connect Server
url: 'http://localhost:8096'
quick_connect: true # use jellyfin quick connect
- name: Password File Server
url: 'http:/jellyfin.example2.com'
username: 'username'
password_file: /home/myusername/.jellyfin-tui-password # use a file containing the password
# All following settings are OPTIONAL. What you see here are the defaults.
# Show album cover image
art: true
# Save and restore the state of the player (queue, volume, etc.)
persist: true
# Grab the primary color from the cover image (false => uses the current theme's `accent` instead)
auto_color: true
# Time in milliseconds to fade between colors when the track changes
auto_color_fade_ms: 400
# Always show the lyrics pane, even if no lyrics are available
lyrics: 'always' # options: 'always', 'never', 'auto'
# Layout mode — 'auto' switches to vertical below vertical_threshold columns
layout: auto # options: 'auto', 'vertical', 'horizontal'
vertical_threshold: 100 # columns; only used when layout is 'auto'
# Swap the play and pause icons
swap_play_pause: false
# Custom symbols — useful for Nerd Font users. Each character of `spinner` is one animation frame.
symbols:
favorite: "♥"
shuffle: "⤮"
play: "►"
pause: "⏸︎"
sleep: "⏾"
downloaded: "⇊"
queued: "◴"
lyrics: "♪"
spinner: "◰◳◲◱"
separator: "›"
disc: "○"
rounded_corners: true
transcoding:
bitrate: 320
# container: mp3
# Discord Rich Presence. Shows your listening status on your Discord profile if Discord is running.
discord: APPLICATION_ID
# Displays album art on your Discord profile.
# "off" - no art (default)
# "musicbrainz" - fetch from MusicBrainz/Cover Art Archive. Does not expose your server URL, but may occasionally miss.
# "local" - use your Jellyfin server !!CAUTION!! exposes your Jellyfin server URL to all Discord users
discord_art: "musicbrainz"
# Sets the text shown in your Discord status. (Listening to {})
# name: jellyfin-tui
# state: artist
# details: track title
discord_status: "state"
# Customize the title of the terminal window
window_title: true # default -> {title} – {artist} ({year})
# window_title: false # disable
# Custom title: choose from current track's {title} {artist} {album} {year}
# window_title: "\"{title}\" by {artist} ({year}) – jellyfin-tui"
# Options specified here will be passed to mpv - https://mpv.io/manual/master/#options
mpv:
replaygain: album
af: lavfi=[loudnorm=I=-23:TP=-1]
no-config: true
log-file: /tmp/mpv.log
# Load custom Lua scripts. Any script in ~/.local/share/jellyfin-tui/mpv-scripts/ is also loaded automatically.
scripts:
- /path/to/script.lua
Click to reveal theming documentation
Jellyfin-tui comes with several built-in themes in both light and dark variants. You can switch between themes in the global popup.
You can also define your own custom themes in the config by selecting a base theme and overriding any colors you want. Custom themes are hot-reloaded when you save the config file.
accent_color fileThe accent color gets written to a file each time it changes. It is located in the DATA_DIR. (for example ~/.local/share/jellyfin-tui/accent_color on linux) and contains the #HEX rgb color. Use it with pywal or similar tools.
"#rrggbb" (hex)"red","white","gray" (named)"auto" → uses the extracted accent from album art"tinted" → keeps the inherited base color but blends it slightly towards the album accent (strength controlled by
tint_strength)"tinted #rrggbb" / "tinted:#rrggbb" → same as above but with an explicit base color"none" → disables optional backgrounds (background,album_header_background only)Full list of keys
| Key | Description |
|---|---|
background |
Main background color. Optional — none uses terminal bg. |
foreground |
Primary text color. |
foreground_secondary |
Secondary text (artists in player, ...). |
foreground_dim |
Dimmed text for less important UI elements. |
foreground_disabled |
Disabled or unavailable UI elements, disliked tracks. |
section_title |
Titles of sections like Albums, Artists, etc. |
accent |
Fallback color for "auto", applied when album art isn't available or if auto_color is disabled. |
border |
Normal border color. |
border_focused |
Border color when a widget is focused. "auto" uses primary (album) color. |
selected_active_background |
Background of the currently selected row the the active section. |
selected_active_foreground |
Text color of the selected row in the active section. |
selected_inactive_background |
Background of selected rows in inactive sections. |
selected_inactive_foreground |
Foreground of selected rows in inactive sections. |
scrollbar_thumb |
Scrollbar handle color. |
scrollbar_track |
Scrollbar track color. |
progress_fill |
Played/filled portion of progress bars. |
progress_track |
Unfilled portion of progress bars. |
tab_active_foreground |
Text color of the active tab. |
tab_inactive_foreground |
Text color of inactive tabs. |
album_header_background |
Background for album/artist header rows (optional). |
album_header_foreground |
Foreground for album/artist header rows. |
tint_strength |
0.0–1.0 float. Controls how much "tinted" colors shift towards the album accent. Stock 0.0, default tinted themes use 0.06. |
themes:
- name: "Transparent Light"
base: "Light"
# remove background
background: "none"
# make active tab text use album accent color
tab_active_foreground: "auto"
- name: "Monochrome Dark (Tweaked)"
base: "Monochrome Dark"
# remove background and album header backgrounds
background: "none"
album_header_background: "none"
# make progress bar follow album accent
progress_fill: "auto"
# high contrast row selection
selected_active_background: "#eeeeee"
selected_active_foreground: "black"
- name: "Gruvbox Dark (Tinted)"
base: "Gruvbox Dark"
# surfaces shift subtly towards the album accent color
tint_strength: 0.08
background: "tinted" # inherits Gruvbox's background and tints it
border: "tinted #3a3a3a" # explicit base color, tinted towards accent
selected_inactive_background: "tinted"
scrollbar_thumb: "tinted #808080"
progress_track: "tinted"
Built-in tinted themes — Tinted Dark and Tinted Light are available out of the box and apply the same treatment to the standard dark/light palettes. Switch to them from the theme picker.
The "auto" accent color is derived from album art by default. You can disable this by setting
auto_color: false
in the config file. This will use the accent color defined in the theme instead for all ""auto"" usages.
jellyfin-tui supports fully customizable key bindings via the config file.
You can:
Press ? inside jellyfin-tui to see all the available actions and your current bindings. Use the action names
exactly as shown there when defining your keymap.
The Help page is the authoritative reference for all actions and bindings.
How to
$ claude mcp add jellyfin-tui \
-- python -m otcore.mcp_server <graph>