A full-featured terminal-based Spotify client built in Rust. Plays audio locally through your terminal using librespot, and provides full playback control, library browsing, search, and queue management via the Spotify Web API.
- Local audio playback via librespot - audio plays directly through your speakers
- Spotify Connect - appears as a device ("Spotify TUI") you can cast to from any Spotify client
- Real-time now-playing display with progress bar
- Full playback control: play/pause, next/prev, seek, volume, shuffle, repeat
- Library browsing: playlists, saved albums, followed artists
- Search: tracks, albums, artists, playlists
- Queue management: view queue, add tracks to queue
- Device switching via Spotify Connect
- Vim-style navigation (j/k, g/G, Ctrl-f/b)
- Rust toolchain (1.70+) — install via rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh - A Spotify Premium account (required for librespot streaming)
- A Spotify Developer application (takes 30 seconds to create)
- macOS / Linux: build tools (Xcode CLT on macOS,
build-essential+libasound2-dev+pkg-configon Debian/Ubuntu)
git clone https://github.com/YOUR_USERNAME/SpotifyTUI.git
cd SpotifyTUI
cargo build --releaseThe binary lands at ./target/release/spotify_tui. Optionally move it onto your PATH:
cp ./target/release/spotify_tui /usr/local/bin/- Go to Spotify Developer Dashboard
- Create a new application (any name/description)
- Add Redirect URI:
http://127.0.0.1:8888/callback - Copy your Client ID and Client Secret
cargo run --release
# or if you moved the binary onto PATH:
spotify_tuiOn first run:
- The app prompts in the terminal for your Client ID and Client Secret, saves them to
config.tomlin the OS config dir:- macOS:
~/Library/Application Support/spotify-tui/config.toml - Linux:
~/.config/spotify-tui/config.toml
- macOS:
- Your browser opens to Spotify's auth page. Click Agree.
- Spotify redirects back to
http://127.0.0.1:8888/callback. The app captures the callback automatically — no need to paste anything. You'll see "Authenticated" in the browser, then the TUI launches. - librespot (the audio engine) does its own one-time browser auth for streaming.
Subsequent runs skip all of this — cached tokens auto-refresh.
Prefer env vars over the TOML? Set SPOTIFY_CLIENT_ID and SPOTIFY_CLIENT_SECRET before running.
- "Failed to bind 127.0.0.1:8888" — another process is using the port (previous instance, a web dev server, etc). Kill it and retry.
- "Token expired" — normal; the app re-auths automatically via cached librespot credentials. Just step through the browser prompt again.
- No audio — confirm Spotify Premium, and pick the "Spotify TUI" device with
Dif playback was happening on another device. - Reset everything — delete the config dir (path printed during first-run) and start over.
Once authenticated, the app registers as a Spotify Connect device called "Spotify TUI". You can:
- Use the TUI to browse and play music (audio streams locally)
- Cast to "Spotify TUI" from any other Spotify client (phone, desktop, web)
- Switch between devices using
Din the TUI
| Key | Action |
|---|---|
Space |
Play/Pause |
n |
Next track |
p |
Previous track |
> / < |
Seek forward/backward (5s) |
+ / - |
Volume up/down (5%) |
Ctrl-s |
Toggle shuffle |
Ctrl-r |
Cycle repeat mode |
r |
Refresh playback state |
| Key | Action |
|---|---|
j / Down |
Select next |
k / Up |
Select previous |
Ctrl-f / Ctrl-b |
Page down/up |
g / G |
Jump to top/bottom |
Enter |
Select/play item |
Tab / Shift-Tab |
Focus next/prev panel |
Backspace |
Go back |
Esc |
Close popup / exit search |
| Key | Action |
|---|---|
1 |
Now Playing |
2 |
Library |
/ |
Search (popup) |
z |
Queue |
| Key | Action |
|---|---|
Z |
Add selected track to queue |
D |
Switch device |
q / Ctrl-c |
Quit |
src/
main.rs - Entry point, initialization
auth.rs - Spotify OAuth authentication with token caching
player.rs - librespot audio player + Spotify Connect (Spirc)
api.rs - Spotify Web API wrapper (playback, library, search, queue)
app.rs - Application state and event loop
input.rs - Keybinding handling
ui/
mod.rs - Main render function, tabs, status bar, popups
playback.rs - Now-playing page and playback bar
library.rs - Library page (playlists, albums, artists, tracks)
search.rs - Search page with results
queue.rs - Queue display
- ratatui + crossterm - Terminal UI framework
- librespot - Spotify protocol, local audio playback, Spotify Connect
- rspotify - Spotify Web API client (OAuth, library, search, playback control)
- tokio - Async runtime