TUI client for yt music
search, browse, and play from your terminal
zig 0.16, single binary
libmpvfor audio- shells out to
curlandyt-dlp - astats lavfi filter for visualizer via
ffmpeg
v0.1.5
- playlists: build as you browse:
Psaves the selected result,Ctrl+Asaves whatever is playing; create a new list or add to an existing list - your playlists sit above recent searches on the search screen
Ctrl+Xtwice deletes the selected playlist or forgets the selected past search;d/Ctrl+Xremoves a track from an open playlistytcli playlists [name]prints them for piping- CJK/emoji titles no longer break the layout
- long queries scroll with the cursor instead of vanishing off the edge
- 5 new themes (tokyonight, catppuccin, matrix, rosepine, solarized)
- frames drawn inside synchronized output — no tearing on theme switch
- recoverable failures land in log and status bar instead of dropping you out
previous
v0.1.4
mmute toggle (now-playing meter readsmute, visualizer idles while muted)Ctrl+Rrepeat mode: off → track → queue (autoplay loops per mode)- volume persists across sessions (saved to config alongside theme)
- tracks over an hour render
h:mm:ss
v0.1.3
- selecting a track stops audio immediately + shows
connecting to YouTube…in the now-playing footer - fix album view mislabeling tracks with a related artist (reads album header, not first channel link)
- fix freeBSD release build (zig 0.16 translate-c: headers pulling
<sys/time.h>, and__sspfortify wrappers →std.c+_FORTIFY_SOURCE=0) - macOS release is now one universal binary (arm64 + x86_64), cross-built +
lipo'd on a single runner - release CI
timeout-minutes
v0.1.2
- failures log to
~/.local/share/ytcli/log(timestamp + cause) - ctrl+c restores cleanly to terminal in all cases
- play video ids beginning with
-(yt-dlp--arg fix) - fix freeBSD build (terminal size via std, not
<sys/ioctl.h>) - readme fix:
brew install mpvalready pulls inyt-dlp,libmpv-devhowever does not
v0.1.1
- github actions for release builds
- prebuilt binaries: macOS, linux, freeBSD
- hardened temp writes (mkstemp, 0600)
v0.1
- autoplays through result list
- drills into albums
- handful of color themes
zig build # → zig-out/bin/ytcli
zig build install --prefix ~/.local # → ~/.local/bin/ytcliinstall ex.
brew install mpv ffmpeg # macOS (mpv pulls in yt-dlp)
apt install libmpv-dev yt-dlp ffmpeg # Debian/Ubuntu[ ! ] currently requires
mpv,ffmpegandyt-dlpparticularly on PATH
macOS (universal: arm64 + x86_64), Linux (arm64/x86_64), and FreeBSD binaries are attached to each release. windows: run under WSL (no native build currently).
ytcli # TUI
ytcli <query> # play first hit
ytcli -s <query> # search, print results
ytcli history # past queries
ytcli playlists # saved playlists (add a name to print its tracks)
ytcli --theme cyan # red (default) | cyan | mono | dracula | nord | gruvbox
# tokyonight | catppuccin | matrix | rosepine | solarized
ytcli --themes # list themes
ytcli -h | -vmade an effort to use commands that felt intuitive
view
search screen: (your playlists, then recent searches — one list)
- text to query,
↑/↓move ⏎opens the selected playlist, or searches the selected/typed querytab/→accept completion (or open the selected playlist)Ctrl+Xtwice — deletes the selected playlist, or forgets the selected past searchescclearCtrl+Tcycle filter (all/songs/videos/albums/artists)
results:
j/kor↑/↓moveg/Gtop/endCtrl+F/Bpageh/escbackPsave to a playlist — never starts playback (pick one, or type a name for a new one)
inside a playlist:
⏎/lplay, queueing the rest of the listdorCtrl+Xremove the selected trackPcopy it into another playlistCtrl+Asaves whatever is playing, from any screen
playback/anytime:
Ctrl+P/spacepauseCtrl+NnextCtrl+Sstop[/]seek ±10s{/}±60s-/=volume ±5 (persists)mmuteCtrl+Rrepeat (off/track/queue)Ctrl+Ytheme
$XDG_DATA_HOME/ytcli/history- query log (falls back to~/.local/share/ytcli/history).$XDG_DATA_HOME/ytcli/log- timestamped failures (search/album/stream) with the underlying error and anycurl/yt-dlpstderr. check here first when something says(see log).$XDG_DATA_HOME/ytcli/playlists- saved playlists:[name]header, then onevideo_id⇥title⇥artist⇥kindline per track. tab-separated, editable by hand.$XDG_CONFIG_HOME/ytcli/config-key=valuesettings.
history is just newline-delimited text - grep/cat it, or seed it so the TUI autocompletes your favorites from the first keystroke:
ex.
printf '%s\n' "elephant gym" "autechre" "john zorn" >> ~/.local/share/ytcli/history
grep -i jazz ~/.local/share/ytcli/history[ ! ] loads newest-first and dedups, so re-seeding or reordering is harmless.
ytcli -s <query> prints title — artist [video_id], one per line; pipe it anywhere. YTCLI_THEME sets the theme without a flag.
[ ! ] requests written to
/tmp/ytcli_body*(mkstemp, 0600, unlinked after) per call + audio streamed/buffered via mpv; not written to disk.
simple spectrum bars via astats lavfi filter
dB to linear/modulated per bar - not a true per-band FFT
please feel free to contribute, not a guarantee it will be merged
[ ! ] thank you for your attention
