Skip to main content

Disco Terminal

CI PyPI Python 3.11+ License: MIT

A Spotify client that runs entirely in your terminal. Album art, a real-time cava audio visualizer, full-app color theming, synced lyrics, and playback control — in iTerm2, kitty, or Windows Terminal, without leaving your shell or focusing the Spotify window. Turn your terminal into a disco.

Disco Terminal — now playing with live visualizer

Yes — everything above is a terminal emulator rendering text.

pipx install discoterminal

See it move

Pick a palette and the whole app rethemes — visualizer, borders, buttons, labels:

Switching color palettes live

Eight visualizer styles (area, bars, mirror, peaks, outline, dots, led, rain):

Cycling visualizer styles

Synced lyrics follow the song, Spotify-style; the card flips between now-playing, artist info, and lyrics:

Lyrics and artist card

More demos & screenshots (search, playlists, playback, cards…)

Search anything

Search feature

Playlists sidebar

Playlist selection

Playback controls

Playback controls

Cards & pickers

Artist info card Lyrics card
Color palette picker Visualizer style picker
Queue viewer Collapsed sidebar & visualizer

Visualizer on / off

Visualizer toggle

Built with Textual. Playback control picks the best backend for your platform automatically:

Platform Local control Visualizer audio
macOS shpotify (AppleScript) BlackHole loopback (setup script included)
Linux playerctl (MPRIS) PulseAudio/PipeWire monitor — works out of the box
Windows (experimental) Spotify Web API cava's native WASAPI loopback

The Spotify Web API (OAuth PKCE) powers your library, search, devices, queue, and is the universal control fallback. Override backend selection with {"backend": "shpotify" | "playerctl" | "webapi"} in config.

Features

  • 🎨 Now playing card with album art (sixel/TGP/halfcell), live progress bar, and click-to-seek
  • 📊 Audio visualizer — embedded cava, 8 render styles (area, bars, mirror, peaks, outline, dots, led, rain), 14 color palettes
  • 🌈 Whole-app theming — pick a palette and every border, button, and label recolors to match
  • 🔀 Card flip — artist info (genres, followers, popularity, top tracks) with artist photo
  • 📻 Your playlists in a collapsible sidebar, fetched live from your account
  • 🔍 Search anything — tracks, albums, playlists, artists — pick from a results modal
  • 🎤 Lyrics via lrclib.net (no API key)
  • Like/unlike the current track, ⏭ queue viewer, 📱 device switcher
  • ⌨️ Everything keyboard-driven; playback via Web API so the Spotify app never steals focus

Install

macOS:

brew install shpotify cava            # local control + visualizer
pipx install discoterminal                 # or: pip install discoterminal
discoterminal

Linux:

sudo apt install playerctl cava       # or your distro's equivalent
pipx install discoterminal
discoterminal

Windows (experimental — testers wanted):

pip install discoterminal                  # control goes through the Web API
discoterminal                              # cava optional; needs a sixel-capable terminal

Requires Python 3.11+ and the Spotify desktop app. The Web API features (playlists, search, queue, lyrics card, artist info) need a Premium account — a Feb 2026 Spotify policy requires Premium for Web-API dev-mode apps. Local playback control via shpotify/playerctl works without Premium.

Spotify API setup (one time)

  1. Go to the Spotify developer dashboard and create an app.

    • If the Web API checkbox is greyed out on the create form (a known dashboard bug): create the app without it, then Edit the app and add Web API there — it won't be greyed out on edit.
  2. Add redirect URI: http://127.0.0.1:8888/callback

  3. Copy the Client ID into ~/.config/discoterminal/config.json:

    { "client_id": "your-client-id-here" }
    

    (or export SPOTIPY_CLIENT_ID=...)

  4. First launch opens a browser to log in once; the token is cached after. No client secret needed — discoterminal uses the PKCE flow.

Visualizer audio setup (macOS only, optional)

Linux and Windows: nothing to do — cava captures system audio natively (PulseAudio/PipeWire monitor, WASAPI loopback).

macOS has no built-in way for apps to hear system output, so cava needs a loopback device:

brew install blackhole-2ch
sudo killall coreaudiod              # load the driver
swift scripts/setup-audio.swift      # create + activate a Multi-Output device

The script builds a "Disco Terminal Multi-Out" device (your speakers + BlackHole) via CoreAudio and switches the system output to it. discoterminal auto-detects BlackHole and points cava at it. Skip all this and the visualizer simply shows a hint instead.

Note: with a Multi-Output device active, macOS volume keys are disabled (aggregate-device limitation). Use discoterminal's +/- — they control Spotify's own volume.

Turn it off / undo:

swift scripts/setup-audio.swift off      # back to speakers (device kept)
swift scripts/setup-audio.swift remove   # back to speakers + delete the device

Re-running without arguments turns it back on. Or just pick any output in System Settings → Sound.

Automatic mode: once the Multi-Out device exists, discoterminal switches to it on launch and restores your previous output on quit — you only run the setup script once, ever. Opt out with {"auto_multiout": false} in config.json.

Keys

Key Action
space Play / pause
n / p Next / previous track
+ / - Volume up / down
l ♥ Like / unlike current track
i Flip card: song ↔ artist info
y Lyrics
u Queue viewer
d Device switcher
/ Search (Enter → results picker)
b Toggle playlist sidebar
v Toggle visualizer
shift+V Visualizer style picker
c Color palette / theme picker
click progress bar Seek
q Quit

Startup arguments: discoterminal next, discoterminal <playlist name>, discoterminal play artist NF — opens the TUI and runs the action.

Config reference

~/.config/discoterminal/config.json:

Key Values Default
client_id Spotify app client ID
visualizer_style area bars mirror peaks outline dots led rain area
visualizer_colors aurora synthwave matrix fire ocean mono sunset vaporwave rainbow ice lava candy gold cyberpunk aurora
art_renderer auto sixel tgp halfcell unicode auto
auto_multiout true / false — switch to Multi-Out on launch, restore on quit (macOS) true
backend shpotify playerctl webapi — override auto-selection auto

Development

pip install -e ".[dev]"
pytest
ruff check src tests
mypy src

Tests run headless with mocked Spotify backends — no account or audio setup needed. CI covers Linux, macOS, and Windows.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

discoterminal-0.2.1.tar.gz (9.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

discoterminal-0.2.1-py3-none-any.whl (33.9 kB view details)

Uploaded Python 3

File details

Details for the file discoterminal-0.2.1.tar.gz.

File metadata

  • Download URL: discoterminal-0.2.1.tar.gz
  • Upload date:
  • Size: 9.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for discoterminal-0.2.1.tar.gz
Algorithm Hash digest
SHA256 57fc6b7138215795b7d87a6578b001ca6746bca6240ec0a57bf321657da10e9f
MD5 ba7a84a2d63bf8822ec527f96527e475
BLAKE2b-256 3c301a3a24a77bfbc1d3472e10d80c8617c37721fb5768537b0ba628966e4e12

See more details on using hashes here.

Provenance

The following attestation bundles were made for discoterminal-0.2.1.tar.gz:

Publisher: publish.yml on VinnyVanGogh/discoterminal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file discoterminal-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: discoterminal-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 33.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for discoterminal-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3bd23126ef27857cc306d9fafedf7ba78b9e7b1be0c28b2e9ff8ae4053f0a9a6
MD5 651e09163f6a9cd9ee6b0a5b6bf38d56
BLAKE2b-256 04becf0dab02b520a629a5880962554aeb118739cca2d6398b53c90fe2c7e57b

See more details on using hashes here.

Provenance

The following attestation bundles were made for discoterminal-0.2.1-py3-none-any.whl:

Publisher: publish.yml on VinnyVanGogh/discoterminal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.3.1

2 files

0.3.0

2 files

0.2.2

2 files

This release

0.2.1 This release

2 files

0.2.0

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 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