Skip to content

Repository files navigation

halpradio — LazyVim-inspired Terminal Internet Radio Streamer

📻 halpradio

The ultimate terminal Internet Radio streaming application for developers who live in the command line.
Built with Go & Bubble Tea, featuring a LazyVim-inspired keyboard-driven interface.

CI Coverage GitHub Release Homebrew Tap Go Version Go Reference Go Report Card License: GPL-3.0 Stations PRs Welcome


⚡ Quickstart (Get listening in 10 seconds)

macOS & Linux via Homebrew

brew install halpworld/tap/halpradio
halpradio

One-Line Shell Installer (macOS & Linux)

curl -fsSL https://raw.githubusercontent.com/halpworld/halpradio/main/install.sh | bash
halpradio

🐳 Instant Container Run (Docker)

docker run --rm -it --device /dev/snd halpworld/halpradio:latest

📺 Live Demo & Real Screenshots

halpradio Interactive Terminal Demo

💼 Activity Modes Landing Page & Split-View Sidebar

halpradio Activity Modes Landing Page — Real Terminal Screenshot

📻 Curated Station Catalog Browser

halpradio Station Catalog Browser — Real Terminal Screenshot

⌨️ WhichKey Overlay & Theme Selection

halpradio WhichKey Help Overlay — Real Terminal Screenshot    halpradio Theme Selection Picker — Real Terminal Screenshot


✨ Why halpradio? (Comparison with Other Terminal Players)

Feature 📻 halpradio PyRadio Curseradio radio-active mocp / cmus
Zero-Dependency Audio Engine Yes (oto/v3 Go native) ❌ (requires MPV/VLC) ❌ (requires MPV) ❌ (requires FFmpeg) ❌ (C daemons)
Linux MPRIS v2 & Media Keys Native D-Bus + playerctl ❌ None ❌ None ❌ None ⚠️ Basic MPRIS
Song Change Desktop Notifications Native macOS/Linux/Win + Dedupe ❌ None ❌ None ❌ None ❌ None
CLI & Hotkey Remote (halpradio remote) macOS Shortcuts, Raycast, tmux ❌ None ❌ None ❌ None ⚠️ Socket
Terminal Party Line (Ctrl+p) P2P Mesh Sync, E2EE Rooms & Reactions ❌ None ❌ None ❌ None ❌ None
Acoustic Fingerprinting (I) Chromaprint / AcoustID + Ad Strip ❌ None ❌ None ❌ None ❌ None
Pomodoro & Sleep Timers (z) Intervals, Station Switch & OS Notify ❌ None ❌ None ❌ None ⚠️ Basic sleep
Beat-Reactive Animated Visualizers 5 Animal DJs + EQ Spectrum ❌ None ❌ None ❌ None ⚠️ Basic VU
Live ICY Metadata (Song / Artist) Real-time Async Extraction ⚠️ Partial ❌ None ⚠️ Partial ⚠️ Track only
30,000+ Online Station Search Built-in RadioBrowser API ❌ Manual list ❌ TuneIn scrap ⚠️ Search only ❌ Local files
Vim Navigation & Which-Key (?) Full Vim Modal UX ⚠️ Basic keys ⚠️ Basic keys ❌ Non-modal ⚠️ Custom maps
Modern Theme Engine 6 Themes (Tokyo Night, Synthwave, etc.) ⚠️ Curses colors ❌ Basic curses ❌ Basic ⚠️ Simple skins
1-Key PR Clipboard Export (p) Instant YAML snippet for PRs ❌ Manual ❌ Manual ❌ Manual ❌ N/A

🎧 Beat-Reactive Animal DJ Visualizers

Press v anytime in halpradio to cycle through 5 animated animal DJs, classic bars, waveform, spectrum, or minimal meters:

Visualizer Mode Animal Character DJ Booth & Live Equalizer Render
dj-cat (default) 🐱 DJ Cat 🎧 (=^・ω・^=)ノ [💿 ◓] ♫ ▂▃▄▅▆
dj-dog 🐶 DJ Dog 🎧 (∪・ω・∪) ノ [💿 ◑] ♫ ▂▃▄▅▆
dj-bear 🐻 DJ Bear 🎧 ʕ •ᴥ•ʔ ノ [💿 ◒] ♫ ▂▃▄▅▆
dj-frog 🐸 DJ Frog 🎧 ( •⊖• ) ノ [💿 ◐] ♫ ▂▃▄▅▆
dj-bunny 🐰 DJ Bunny 🎧 ( •ㅅ• ) ノ [💿 ◓] ♫ ▂▃▄▅▆
bars 📊 Bars Equalizer ♫ ▂▃▄▅▆▇█▇▆▅▄▃▂ ♬
wave Waveform ∿ _⎽⎼─⎻⎺▔⎺⎻─⎼⎽_ ∿
spectrum 🔊 Spectrum 🔊 BASS ███ MID ███ TREB ███
minimal 🎚️ Minimal VU L:████░░░░ R:██████░░
  • Zero-Jitter Normalized Poses: Every pose (head + arm + deck) has an exact, invariant width (24 visual columns) for smooth, stable rendering without horizontal shifting.
  • Harmonic Multi-Frequency Equalizer Rack: Solid 6-bar mini-EQ ( ▂▃▄▅▆) driven by harmonic frequency physics (sub-bass kick, mid melody, treble shimmer) with smooth attack and exponential decay.
  • Rhythmic Groove: Head bobbing and turntable vinyl rotation (, , , ) tempo-matched to audio playback.
  • Sleep State: When stopped/paused, the DJ rests peacefully on the turntable (🎧 (= - ω - =)..zzZ [ 💿 ] ⏹ STOPPED).

⏱️ Developer Pomodoro Focus Mode & Sleep Timer

Press z or Z anywhere in halpradio to open the Timer & Pomodoro Focus Modal:

🍅 Pomodoro Focus Sprints  |  ☕ Short & Long Breaks  |  ⏳ Sleep Timer with Volume Fade-Out

🍅 Developer Pomodoro Mode

  • Sprint & Rest Intervals: Seamlessly cycle between Focus sessions (default: 25 min), Short Breaks (5 min), and Long Breaks (15 min after 4 completed cycles).
  • Auto Station Switching: Automatically tune into your deep focus station (e.g. Lofi Girl / Synthwave) during sprints, and switch to relaxing sounds (e.g. Ambient Cafe / Jazz) or silence during breaks.
  • Live Visual Countdown: Real-time progress bar and badges displayed directly in the playerbar (🍅 18:42 (#2/4) / ☕ 04:50 (Break)), statusbar, and OSC native terminal tab title ([🍅 18:42] ▶ Track | halpradio).

⏳ Sleep Timer & Smooth Volume Fade-Out

  • Quick Presets: Instant 15 min, 30 min, 45 min, 60 min, 90 min, or custom minute countdowns.
  • Graceful Volume Fade-Out: Smoothly scales audio volume down to 0% during the final 10 seconds before stopping playback, keeping your initial volume preference intact for next morning.

🔔 System Desktop Events & OS Integration

  • Cross-Platform Desktop Notifications: Silent native banner notifications on macOS (osascript), Linux (notify-send), and Windows (PowerShell toast notifications).
  • Terminal Bell (\a): Optional audio bell cue on interval transitions.
  • Custom Shell Event Hook: Execute your own shell script on timer transitions with rich environment variables (HALPRADIO_EVENT, HALPRADIO_PHASE, HALPRADIO_CYCLE, HALPRADIO_STATION_NAME), perfect for triggering macOS Focus Mode, smart desk lights, Waybar/Polybar, or Slack status!

📦 Complete Installation Options

Method 1: Homebrew (macOS & Linux) — Recommended

# Install directly from the official tap
brew install halpworld/tap/halpradio

To upgrade anytime:

brew upgrade halpradio

Method 2: One-Line Installer Script (macOS & Linux)

Automatically detects your OS and architecture (arm64 / amd64), downloads the latest release binary, and installs it to /usr/local/bin:

curl -fsSL https://raw.githubusercontent.com/halpworld/halpradio/main/install.sh | bash

Method 3: Pre-Compiled Binary Releases

Download pre-compiled standalone tarballs from the GitHub Releases page:

Platform Architecture Package
macOS Apple Silicon (M1/M2/M3/M4) halpradio_*_darwin_arm64.tar.gz
macOS Intel x86_64 halpradio_*_darwin_amd64.tar.gz
Linux x86_64 halpradio_*_linux_amd64.tar.gz
Linux ARM64 / Raspberry Pi / AWS Graviton halpradio_*_linux_arm64.tar.gz
Windows x86_64 / ARM64 halpradio_*_windows_*.zip

Method 4: Go Install

If you have Go 1.21+ installed:

go install github.com/halpworld/halpradio@latest

Method 5: Build From Source

git clone https://github.com/halpworld/halpradio.git
cd halpradio
go build -o halpradio main.go
./halpradio

For Arch Linux (AUR), Scoop (Windows), or Nix packaging, see the Packaging Guide.


🔊 Audio Player Backends & Codec Support

halpradio works completely out of the box using its built-in native Go audio engine (oto/v3 + go-mp3) with zero external binary dependencies required!

Audio Backend Priority MP3 AAC OGG FLAC HLS / M3U8 Dependencies
mpv (recommended) 1st brew install mpv / apt install mpv
vlc / cvlc 2nd brew install vlc / apt install vlc
ffplay 3rd ffmpeg
native (Go oto) 4th Zero dependencies (built-in)

halpradio will automatically detect mpv > vlc > ffplay > native on startup. You can override this anytime with the -backend flag:

halpradio -backend mpv
halpradio -backend native

🖥️ Desktop Integration: Discord RPC, Status Bar IPC, MPRIS v2 & Media Keys

halpradio provides deep desktop operating system integration across macOS and Linux:

🎮 Discord Rich Presence (RPC)

Shows live radio playback activity directly on your Discord profile in real time:

  • Station Name: e.g. SomaFM Groove Salad
  • Track Info: e.g. Tycho - A Walk (or Streaming Live...)
  • Active Animal DJ Avatar: Matches your active visualizer (dj_cat, dj_dog, dj_bear, dj_frog, dj_bunny).
  • Duration: Live elapsed listening timer.
  • Non-blocking and silent failover if Discord is not running.
  • Toggle via -discord=false flag or discord_rpc: false in config.yaml.

📊 Status Line Query Mode (tmux, Waybar, SketchyBar, Polybar)

Query the running instance instantly from scripts and custom desktop status lines without opening the TUI:

# Plain text output for status lines
halpradio current
# Output: SomaFM Groove Salad: Tycho - A Walk

# Full JSON metadata payload for Waybar / Polybar / SketchyBar
halpradio current --json
# Output:
# {
#   "status": "playing",
#   "station_id": "somafm_groovesalad",
#   "station_name": "SomaFM Groove Salad",
#   "artist": "Tycho",
#   "title": "A Walk",
#   "bitrate": 128,
#   "backend": "mpv",
#   "volume": 80,
#   "visualizer": "dj-cat"
# }

🍎 Remote Controls & Hotkey Scripting

Control playback instantly from the terminal, window managers (i3/sway/hyprland), Raycast, Alfred, or tmux:

# Convenience shortcuts:
halpradio toggle       # Toggle play / pause
halpradio next         # Jump to next station
halpradio prev         # Jump to previous station
halpradio stop         # Stop playback
halpradio current      # Query current station & track

# Subcommand style:
halpradio remote toggle
halpradio remote volup       # Volume +5%
halpradio remote voldown     # Volume -5%
halpradio remote mute        # Toggle mute
halpradio remote random      # Play random station
halpradio remote status      # Inspect full status
  • macOS Shortcuts / Raycast / Alfred: Map halpradio toggle or halpradio next to media keys or hotkeys.
  • tmux: Add bind-key P run-shell "halpradio toggle" and set -g status-right "#(halpradio current)" to ~/.tmux.conf.
  • Waybar: Add custom module with exec: "halpradio current --json", return-type: "json".

🐧 Linux MPRIS v2 D-Bus Interface

Registers standard D-Bus service org.mpris.MediaPlayer2.halpradio on the session bus.

  • Control halpradio seamlessly from your keyboard media keys, GNOME / KDE Plasma media panels, and Waybar/Polybar modules.
  • Supports standard MPRIS methods: PlayPause, Play, Pause, Stop, Next, Previous, Quit.
  • Control from terminal: playerctl play-pause, playerctl next, playerctl previous, playerctl stop.

📢 Song Change Desktop Notifications

Whenever a radio station broadcasts a new track title via ICY metadata, halpradio fires a native desktop notification banner:

  • Title: 📻 halpradio — [Station Name]
  • Body: 🎶 [Artist] - [Title]
  • Built-in deduplication ensures zero spam.
  • Toggle via -notifications=false or song_notifications: false in config.yaml.

🎧 Automatic Headphone Pause (macOS)

When the default audio output device leaves Bluetooth — e.g. AirPods taken out of the ears or the case closed — playback pauses automatically, matching macOS Music behavior:

  • Works with every backend (mpv, vlc, ffplay, native, ...).
  • Toggle via -autopause=false or autopause: false in config.yaml.

🔍 Real-Time Acoustic Stream Fingerprinting & Dirty Metadata Sanitizer

Tired of stations broadcasting mystery tracks with zero metadata, or streams polluted with ads, jingles, station slogans, and website URLs? halpradio features an acoustic stream recognition engine and intelligent metadata sanitizer:

🎙️ On-Demand Song Identification (I key)

  • Instant Recognition: Press I anywhere during playback to identify what is playing directly from raw audio PCM data.
  • Chromaprint & AcoustID: Captures a 5-second sample buffer, computes audio subfingerprints (using fpcalc or pure-Go fallback), and queries the AcoustID and MusicBrainz databases.
  • Visual Confidence Score: Displays the matched artist, song, album, year, and a live confidence bar directly in the playerbar ([✨ Identified via AcoustID (94%)] / ████████░ 94%).
  • Auto-Identify Mode: Set auto_identify: true in config.yaml or launch with --auto-identify to automatically fingerprint songs on streams that lack ICY metadata after 20 seconds.
  • Clipboard & Search Integration: Yanking (y) copies the verified track title to your clipboard. Searching (o) immediately opens Spotify, Apple Music, or YouTube with clean metadata.
  • Persistent History (H): Identified tracks are automatically recorded to the History tab with a star badge.
  • Graceful Offline Fallback: If offline or if the database cannot find a match, the player falls back cleanly without interrupting playback.

🧼 Dirty Metadata Sanitizer

Internet radio ICY streams often emit dirty titles like: LIVE NOW: Tycho - A Walk (Buy on Somafm.com) // Best Chill Music! - 128kbps

halpradio continuously cleans ICY stream titles with built-in regex sanitizers:

  • Strips advertisements, sponsors, promotional URLs, and "Buy on ..." text.
  • Removes radio jingles, slogans, frequencies (104.5 FM), and station station identifiers.
  • Cleans composite delimiters, extra brackets, and bitrate tags while preserving genuine artist and song titles.

📜 Real-Time Synced Karaoke Lyrics & Multi-Protocol Terminal Album Art

Modern terminals grew real graphics capabilities, so halpradio uses them. Press L for a live lyric sheet that scrolls itself, and A for the cover art of whatever is on air — all without leaving the terminal.

🎤 Live Synced Lyrics Drawer (L key)

  • LRCLIB First: Queries LRCLIB with the artist, title and duration taken from ICY stream metadata or the acoustic fingerprint, then falls back to NetEase when LRCLIB has no match.
  • Auto-Scrolling Karaoke View: When timestamped .lrc data exists, the drawer highlights the line being sung, fades the surrounding lines, and draws a progress gauge across the active line.
  • Manual Scroll For Plain Text: Unsynced lyrics render as a formatted sheet you scroll with j / k.
  • Sync Nudge: Internet radio exposes no seek position, so the lyric clock starts when the station announces a new title. Press , and . to shift the sync in 0.5 second steps when a station announces late or early.
  • Never Blocks The UI: Every lookup runs as a Bubble Tea command off the update loop, so the TUI stays responsive on slow connections.
  • Fits Any Terminal: At 80 columns or wider the drawer takes its own columns rather than overlapping the station list; below that the sheet becomes a full-width overlay, and resizing moves it between the two without closing it.
  • Disk & Memory Cache: Sheets are memoised in RAM and cached under ~/.cache/halpradio/lyrics/, and stations with no match are negative-cached so the APIs are not hammered every track.

🖼️ Multi-Protocol Album Art (A key)

halpradio detects your terminal's best image transport at startup and encodes artwork for it:

Priority Protocol Terminals
1 Kitty Graphics Ghostty, Kitty, WezTerm
2 iTerm2 Inline Images iTerm2, WezTerm
3 Sixel Foot, xterm, mlterm, yaft
4 Truecolor Half-Block every 24-bit colour terminal
5 Braille 256-colour and monochrome fallback
  • High-Res Cover Lookup: Artwork is resolved from the iTunes Search API, Deezer, MusicBrainz plus the Cover Art Archive, and Last.fm when you supply lastfm_api_key.
  • No Distortion On Basic Terminals: The half-block and Braille renderers letterbox the image to keep covers square, and every renderer emits output padded to an exact cell grid so the surrounding layout never shifts.
  • Two Surfaces: A thumbnail sits at the top of the lyrics drawer, and A opens a floating full-size viewer showing the album, the provider and the active protocol.
  • Cached Locally: Downloaded covers live under ~/.cache/halpradio/art/.
┌─ 📻 CATALOG ──────────────────┬─ 📜 LIVE LYRICS ───────────────┐
│  ▶ SomaFM Groove Salad        │      ▄▄▄▄▄▄▄▄▄▄▄▄              │
│    Nightwave Plaza            │      █ ALBUM ART █             │
│    Radio Paradise             │      ▀▀▀▀▀▀▀▀▀▀▀▀              │
│    KEXP 90.3                  │       🖼 iTunes                 │
│                               │  Tycho - A Walk                │
│                               │                                │
│                               │    I've been wandering         │
│                               │  ► Searching for a signal ◄    │
│                               │    Everything is quiet         │
│                               │  ━━━━━━━━━━━───────            │
│                               │  ⏱ Synced via LRCLIB           │
│                               │  L close · , . sync            │
└───────────────────────────────┴────────────────────────────────┘

Tune the feature from ~/.config/halpradio/config.yaml:

lyrics_enabled: true          # LRCLIB / NetEase synced lyrics engine
lyrics_auto_open: false       # open the drawer on startup
lyrics_offset_ms: 0           # persistent sync correction
album_art_enabled: true       # terminal cover art renderer
album_art_protocol: auto      # auto | kitty | iterm2 | sixel | halfblock | braille | off
lastfm_api_key: ""            # optional extra cover art provider

Set HALPRADIO_NO_ART=1 to disable image rendering for a single run, or HALPRADIO_ART_PROTOCOL=halfblock to force a transport when detection guesses wrong.


🎉 Terminal Party Line: P2P Mesh Synchronized Radio Rooms & Reactions

Share the groove with teammates, study groups, or friends with zero central audio relaying! halpradio features an end-to-end encrypted (E2EE) P2P mesh party system powered by WebRTC data channels:

👥 In-TUI Party Manager (Ctrl+p)

  • Quick Create & Join: Press Ctrl+p anywhere in the app to host a new room with a memorable 6-character room code (e.g. #8X2K9P) or join an existing session.
  • Argon2id & AES-256-GCM Encryption: Every party room derives high-entropy session keys with Argon2id and encrypts all peer-to-peer control traffic using AES-256-GCM with CSPRNG nonces.
  • Zero Central Audio Relaying: Audio streams directly from the source radio broadcast on each client while synchronization commands and metadata travel peer-to-peer over WebRTC data channels.
  • DJ Pass Governance: Host can choose Host Only (only the room creator can change stations) or Open Democracy (any participant can tune stations).
  • Sub-Second Playback Sync: Late-joining listeners automatically tune to the room's current broadcast with sub-second clock sync.
  • Deterministic Host Election: If the room host disconnects, peers deterministically elect a successor host without interrupting playback.

🎈 Live ASCII Reactions & Mini-Chat

  • While in an active party room, press 1 - 5 anytime to float live reactions across connected listeners' terminals:
    • 1: 🔥 Fire
    • 2: ❤️ Heart
    • 3: ☕ Coffee
    • 4: 🚀 Rocket
    • 5: 👀 Eyes
  • Floating reactions rise and decay gracefully over 3.5 seconds in the party bar without disturbing your TUI view.

⌨️ CLI Party Commands

Control and join party rooms directly from your shell or tmux sessions:

halpradio party create "team-focus"       # Create room and launch TUI
halpradio party create --dj-pass=open     # Create room with democratic DJ control
halpradio party create --headless         # Host room headlessly in server / tmux
halpradio party join 8X2K9P               # Join room #8X2K9P with interactive TUI
halpradio party status                    # Inspect current room, listener count, and host
halpradio party react 1                   # Send 🔥 reaction to current room
halpradio party chat "Loving this track!"  # Send mini-chat ping to room
halpradio party leave                     # Disconnect from current room

⌨️ Navigation & Keybindings (Vim & Media Style)

Press ? or F1 anywhere in halpradio to open the floating WhichKey Overlay.

Category Keybinding Action
Navigation j / k or / Move down / up
n / ] Jump and play Next station in active list
N / [ Jump and play Previous station in active list
h / l or / Focus sidebar / main list or prev/next tab
1 - 9 (0) Direct jump to Tab (1: Activities, 2: Catalog, 3: Countries, 4: Genres, 5: Favorites, 6: Online, 7: Custom, 8: History, 9: Globe, 0: Tuner)
C Jump directly to Countries / FM tab
H Jump directly to Track History tab
9 / M Jump directly to 3D Globe Explorer
0 / F Jump directly to Analog Frequency Tuner (experimental)
g / G Jump to top / bottom of list
Ctrl+u / Ctrl+d Half page up / down
Discovery & Sharing Ctrl+p Open Party Room Manager (P2P mesh synchronized listening & room setup)
1 - 5 Send live floating ASCII reaction (🔥 ❤️ ☕ 🚀 👀) when in Party Room
I Identify playing track via acoustic stream fingerprinting (Chromaprint / AcoustID)
L Toggle live synced lyrics drawer (LRCLIB / NetEase)
A Toggle album art viewer (Kitty / Sixel / iTerm2 / half-block)
, / . Nudge lyric sync backward / forward by 0.5s (lyrics drawer open)
y Yank / copy track metadata (Artist - Title) or identified song to system clipboard
o Open streaming search in default web browser (Spotify, YT Music, Apple, DDG, Google)
s Star / bookmark track to ~/.config/halpradio/saved_tracks.txt (on History tab)
c Clear track history log (on History tab)
p Export station YAML snippet to clipboard for GitHub PR
Playback Space / Enter / ⏯️ Toggle Play / Pause selected station (or tune in from history)
s / x / ⏹️ Stop audio stream (on station tabs)
z / Z Open Sleep Timer & Pomodoro Focus modal
r / R Play random station
+ / - / = / > Volume up / down (5% step, supports ANSI, ISO, AZERTY, QWERTZ)
m / M / 0 Mute / unmute
v Cycle visualizer (dj-cat, dj-dog, dj-bear, dj-frog, dj-bunny, bars, wave, spectrum, minimal)
b Switch dial band (FM / AM / SW) in frequency tuner mode
Catalog f Toggle Favorite star ⭐
/ Live fuzzy search / filter stations
w / c Jump & filter by Activity Mode / Genre Category
a Open Add Custom Station modal
e / d Edit / Delete local custom station
UI & Options P Open Plugins & Extensions Manager (Wasm Sandbox)
t Theme picker modal (Tokyo Night, Catppuccin, Synthwave, etc.)
? / F1 Toggle WhichKey help overlay
q / Ctrl+c Quit halpradio

🔌 Sandboxed WebAssembly Plugins & Official Registry

halpradio includes a secure, capability-based WebAssembly (Wasm) Plugin Engine powered by tetratelabs/wazero (zero CGo, pure Go) and an official community registry at halpworld/halpradio-plugins.

🖥️ In-App Plugin Manager (P key)

  • Press P anywhere in halpradio to browse installed plugins and explore the official online registry.
  • 1-click install, enable/disable toggle, and interactive capability permission review modal (network whitelists, isolated storage).

⌨️ CLI Plugin Commands

halpradio plugin list                  # List installed and official registry plugins
halpradio plugin install <plugin-id>   # Install plugin from official registry with SHA-256 verification
halpradio plugin enable <plugin-id>    # Enable plugin
halpradio plugin disable <plugin-id>   # Disable plugin
halpradio plugin remove <plugin-id>    # Uninstall plugin
halpradio plugin update --all          # Update plugins to latest version

🌟 Official Plugins

  • Webhook Broadcaster: Broadcasts now-playing tracks to Discord, Slack, or Home Assistant webhooks in real-time.
  • Scrobble Logger & Stats: Records station play counts, tracks listening milestones, and persists stats 100% offline.

👉 Want to build your own plugin? Check out the Plugin Developer SDK & Starter Template!


🎨 Themes & Community Themes Hub

Switch themes on the fly by pressing t or pass -theme <name> via CLI:

  • 🌌 Tokyo Night (tokyonight) — Neon blue and purple developer aesthetic
  • Catppuccin Mocha (catppuccin) — Soothing pastel dark palette
  • 🌆 Retro Synthwave '84 (synthwave) — Vibrant neon magenta and cyan
  • ❄️ Nord (nord) — Cool arctic blue minimalism
  • 🪵 Gruvbox Dark (gruvbox) — Warm retro terminal tones
  • 🧛 Dracula (dracula) — High-contrast gothic vampire theme

🌐 In-App Community Hub & Live Preview (t -> Tab)

  • Discover & Download: Press t then Tab to enter the Community Hub ([2] 🌐 Community Hub). Browse dozens of online community palettes (Rosé Pine, Everforest, Kanagawa, Monokai Pro, One Dark Pro, Cyberpunk 2077, Cyberdream, etc.) and press i or Enter to download & apply instantly.
  • 👁️ Live Preview: Press p on any theme to preview it live in your full terminal interface before downloading or saving! Press p or Esc to revert.
  • Filter & Search: Press / in the Community Hub to filter themes by name, style, or author.

⌨️ CLI Theme Commands

halpradio theme list                  # List installed and community hub themes
halpradio theme preview rose-pine     # Preview color swatches & mockup in terminal
halpradio theme install rose-pine     # Download and install from themes repo
halpradio theme info everforest       # Inspect semantic color tokens
halpradio theme export my-theme       # Export active palette as YAML starter
halpradio theme remove my-theme       # Uninstall custom theme

Explore and contribute community themes in the official halpradio-themes repository.


📻 Curated Station Categories & Activity Modes

Explore hundreds of curated streams across diverse activity moods and global genres:

  • 🎧 Focus & Flow: Lofi Girl Radio, Chillhop Music, SomaFM Groove Salad, DEF CON Radio, Nightwave Plaza
  • Acoustic & Coffee: Cafe De Paris, Smooth Jazz Florida, Swiss Classic, Instrumental Ambient
  • 🚀 High Energy Coding: Synthwave 1980s, Cyberpunk FM, Goa Psytrance, Digitally Imported (DI.FM)
  • 🌏 Global Radio: BBC Radio 6 Music (UK), KEXP 90.3 FM Seattle (US), Radio Paradise (US), FM 802 Osaka (JP), Big B Radio K-Pop (KR), FIP Radio (FR), Triple J (AU)
  • 📰 News & Public Broadcasts: NPR 24 Hour Program Stream, BBC World Service, Deutschlandfunk

🐛 Troubleshooting & Debug Logs

If halpradio misbehaves — a freeze, silent playback, a station that never connects — run it with --debug:

halpradio --debug

Diagnostics are written to ~/.config/halpradio/debug.log (override with --debug-log <path>, or set HALPRADIO_DEBUG=1). The log records the halpradio version, OS, terminal, selected audio backend, the exact player command line, every keystroke the UI handled, and the state of the desktop integrations (MPRIS, IPC, Discord).

Because the TUI runs a single-threaded update loop, a freeze is almost always something blocking inside it. A built-in watchdog notices when the loop has been stuck for more than five seconds and appends a full goroutine dump to the log, which usually names the culprit outright:

14:02:11.884 [update] → Update KeyMsg "enter"
14:02:16.885 [watchdog] STALLED: Update KeyMsg "enter" (stuck 5.001s)
14:02:16.885 [watchdog] goroutine dump (stalled operation): ...

So if the UI locks up, wait about ten seconds before killing halpradio (from another terminal: pkill halpradio), then attach debug.log to your bug report.

The log contains station stream URLs and local file paths; it is written with 0600 permissions, and it never records credentials. Skim it before pasting it into a public issue.


📚 Technical Documentation

Explore detailed technical documentation in the docs/ folder:


🤝 Contributing New Stations

We love community contributions! Expanding the catalog takes less than 30 seconds:

  1. Select any station in halpradio and press p (copies formatted YAML to clipboard).
  2. Paste the snippet into stations.yaml and submit a Pull Request.
  3. Alternatively, submit a Station Suggestion Issue.
  4. See CONTRIBUTING.md for full guidelines.

📄 License

This project is licensed under the GNU General Public License v3.0 (GPL-3.0).


Made with ❤️ for terminal lovers and internet radio enthusiasts.

About

📻 LazyVim-inspired Terminal Internet Radio Streamer built with Go & Bubble Tea. 30,000+ stations, beat-reactive animal DJ visualizers, live ICY metadata, and zero-dependency audio.

Topics

Resources

Contributing

Security policy

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages