A terminal-based client for Jellyfin that lets you browse your media library and play videos via mpv. Inspired by jftui.
- Uses your mpv config!
- Resumes playback!
- Tracks playback progress and updates jellyfin!
- Automatic segment (intro, etc.) skipping!
- No mouse required!
On Arch Linux, jfsh can be installed from the AUR
yay -S jfshRun jfsh directly from GitHub:
nix run github:hacel/jfshOr install it into your user profile:
nix profile install github:hacel/jfshThe Nix package uses an existing mpv from PATH when available and provides
the packaged mpv as a fallback.
Download the latest pre-built binary for your platform from the releases page.
go install github.com/hacel/jfsh@latest-
Start jfsh
jfsh
-
Login
On first launch, you'll be prompted to enter:
- Host: e.g.,
http://localhost:8096 - Username
- Password
- Host: e.g.,
-
Play Media
- Select an item and press Enter or Space to play it.
mpvwill launch and begin streaming.
-
Quit
- Press
qat any time to exit jfsh.
- Press
By default, the configuration file is stored in $XDG_CONFIG_HOME/jfsh/jfsh.yaml. If $XDG_CONFIG_HOME is not set it defaults to:
- Linux:
~/.config/jfsh/jfsh.yaml - macOS:
~/Library/Application Support/jfsh/jfsh.yaml - Windows:
%APPDATA%/jfsh/jfsh.yaml
host: http://localhost:8096
username: me
device: mycomputer # Device name to report to jellyfin (default: hostname)
password_file: /run/secrets/jfsh-password # Optional runtime secret file
skip_segments: # Segments to automatically skip (default: [])
- Recap
- Preview
- Intro
- OutroWhen no reusable token or password_file is available, jfsh prompts for the
password. Passwords are never stored by jfsh. Authentication tokens and the
generated device ID are stored in $XDG_STATE_HOME/jfsh/state.yaml.
The flake exports homeManagerModules.default. Import it into a standalone
Home Manager configuration or under home-manager.users.<name> in NixOS:
{
imports = [ inputs.jfsh.homeManagerModules.default ];
programs.jfsh = {
enable = true;
settings = {
host = "https://jellyfin.example.com";
username = "me";
device = "mycomputer";
skipSegments = [
"Recap"
"Intro"
"Outro"
];
};
passwordFile = "/run/secrets/jfsh-password";
};
}Add jfsh to the consuming flake and share its existing inputs:
inputs.jfsh = {
url = "github:hacel/jfsh";
inputs.nixpkgs.follows = "nixpkgs";
inputs.home-manager.follows = "home-manager";
};passwordFile must be an absolute runtime path. It is a string rather than a
Nix path so the password is not copied into the Nix store. The file can be
provided by a secret manager such as sops-nix or agenix. Omit it to enter the
password interactively on first authentication.
The legacy password, token, user_id, device_id, and client_version
configuration keys are ignored. Remove them manually, especially the plaintext
password, and authenticate once to create the new state file. Existing
host, username, device, and skip_segments settings continue to work.
By default, no segments are automatically skipped. To enable skipping segments you must add skip_segments to the configuration file. Possible values for skip_segments are the segment types in Jellyfin which are: Unknown, Commercial, Preview, Recap, Outro and Intro.
- Configuration through TUI
- Complete library browsing
- Sorting
- Better search: Filter by media type, watched status, and metadata
