chill

command module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 20, 2026 License: MIT Imports: 37 Imported by: 0

README

chill

Terminal lofi radio. Streams the best 24/7 lofi beats from YouTube.

chill playing chillhop, with suggestions open in the REPL

Install

Requires mpv and yt-dlp.

macOS:

brew install mpv yt-dlp

Linux:

sudo apt install mpv pipx
pipx install yt-dlp

Windows:

choco install mpv yt-dlp

Then install chill:

go install github.com/willibrandon/chill@latest

Or grab a binary for your platform from the releases page and put it somewhere in your PATH.

To update an installed copy:

chill update

chill -update, chill --update, and chill upgrade work too. This downloads the latest release for your platform, verifies its checksum, and updates the running daemon while preserving playback settings.

Make sure your Go bin directory is in your PATH:

  • macOS/Linux: export PATH="$HOME/go/bin:$PATH"
  • Windows: Add %USERPROFILE%\go\bin to your PATH

Usage

chill                # play default station (starts daemon automatically)
chill chillhop       # play specific station
chill -i             # interactive mode (repl)
chill --skip         # skip to random station
chill --toggle       # pause/resume
chill --vol 60       # set volume (also +5, -10, up, down)
chill --mute         # toggle mute
chill --status       # show what's playing
chill --stop         # stop playback
chill --list         # show all stations
chill add n url desc # save your own station
chill remove n       # remove a custom station or restore a built-in
chill default n      # choose the station played by chill
chill --sleep 45m    # stop playback after 45 minutes
chill --sleep off    # cancel the sleep timer
chill --version      # show version
chill update         # install the latest release
chill --fg           # run in foreground (no daemon)

Architecture

chill uses a client-server architecture. The first playback command spawns a background daemon. CLI commands and the REPL communicate with that daemon over IPC: a Unix socket on macOS/Linux, or localhost TCP on Windows.

The daemon starts and supervises mpv, sends playback controls over mpv's JSON IPC, and listens for player events to track loading and failures. This second connection uses a Unix socket on macOS/Linux and a named pipe on Windows. mpv uses yt-dlp to resolve YouTube streams.

┌─────────────┐      ┌─────────────┐           ┌─────────────┐
│ chill       │ ◀──▶ │ daemon      │ ◀───────▶ │ mpv         │
│ (CLI/REPL)  │ IPC  │ (server)    │ JSON IPC  │ (playback)  │
└─────────────┘      └─────────────┘           └─────────────┘

This means:

  • Music keeps playing after the command exits
  • Control playback from any terminal
  • Playback controls use the running player; starting a stream still takes time
  • The daemon owns reconnects and sleep timers, so they work after the client exits

After installing a newer version, your next command automatically upgrades an outdated daemon. Playback restarts once, preserving your station, volume, mute, pause state, and sleep timer.

Volume, mute, and pause/resume use mpv's native IPC controls, so adjusting the volume never restarts the stream or resumes paused music. Mute preserves your volume, and the last volume is remembered across daemon restarts in state.json beside the station config. Mute itself is temporary.

Status distinguishes loading, playing, paused, failed, and idle. If a stream drops or fails to load, chill reports the player error and retries up to three times, after 1, 2, and 4 seconds. Each load has a 45-second timeout. A minute of successful playback replenishes the retry budget. Errors and retry progress also appear in the REPL; use play or choose another station to try again after the retries are exhausted.

Sleep timer

While a station is playing or loading, chill --sleep 45m schedules playback to stop. Durations accept units such as 30s, 45m, or 1h30m. A new timer replaces the previous one; chill --sleep off cancels it. chill --status and the REPL status bar show the remaining time.

The timer continues while paused, switching stations, or reconnecting. When it expires, playback stops and the daemon becomes idle; chill --toggle starts the default station again. Explicitly stopping chill clears the timer. Timers are not restored across daemon restarts.

Stations

Station Description
lofi-girl Lofi Girl - beats to relax/study to
chillhop Chillhop Radio - jazzy & lofi hip hop
chillout Chillout Lounge - calm & relaxing
code-radio Code Radio - beats to study & code to
sleep Lofi - beats to sleep/relax to
study Lofi - beats to study/relax to
Your own stations

Add any YouTube stream with chill add <name> <url> [description], or edit the station config:

  • macOS: ~/Library/Application Support/chill/stations.json
  • Linux: ~/.config/chill/stations.json (or $XDG_CONFIG_HOME/chill/stations.json)
  • Windows: %AppData%\chill\stations.json
{
  "default_station": "synthwave",
  "stations": [
    {
      "name": "synthwave",
      "url": "https://www.youtube.com/watch?v=4xDzrJKXOOY",
      "desc": "Synthwave Radio - retro electronic beats"
    },
    {
      "name": "jazz",
      "url": "https://www.youtube.com/watch?v=HuFYqnbVbzY",
      "desc": "Jazz Cafe - smooth jazz for work"
    },
    {
      "name": "rain",
      "url": "https://www.youtube.com/watch?v=mPZkdNFkNps",
      "desc": "Rain on a window - for deep focus"
    }
  ]
}

A station with the name of a built-in overrides it. chill remove <name> removes a custom station; removing an override restores the built-in. Built-ins cannot be removed. chill default <name> chooses what chill, REPL play, and chill --fg play without a station argument. The initial default is lofi-girl; removing a custom station that was the default returns to lofi-girl.

Add, remove, and default commands update the running daemon automatically. For manual file edits, use chill -i then reload, or restart the daemon. Reload rebuilds the list from the built-ins and the current file, including removals. Reloading or removing a station does not interrupt a stream already playing.

Interactive Mode

chill -i opens a fullscreen REPL that suggests commands and stations as you type, shown above.

Commands: play, vol, mute, skip, pause, resume, toggle, status, list, add, remove, default, sleep, reload, stop, clear, help, quit. A station name on its own plays that station.

Use sleep 45m or sleep off for the timer. sleep on its own still plays the sleep station, as does play sleep.

Key
Tab complete with the highlighted suggestion
→ take the ghost text
↑ / ↓ pick a suggestion, otherwise walk through history (kept across sessions)
Enter run the line, or take a suggestion picked with ↑ / ↓
Esc dismiss the suggestions
PgUp / PgDn scroll the transcript, so does the mouse wheel
Shift+↑ / Shift+↓ select lines of the transcript
y / Enter / Ctrl+C copy what is selected
mouse drag to select, right click to copy, or to paste when nothing is selected
Ctrl+C clear the line, when nothing is selected
Ctrl+L clear the screen
F1 help
Ctrl+Q quit, music keeps playing

Foreground Mode

Use --fg to run in the terminal with mpv controls:

Key Action
q quit
m mute
9 / 0 volume down / up
← / → seek

Build and test

go build .
go test ./...

With mpv installed, run the playback integration test:

CHILL_TEST_MPV=1 go test -count=1 -run TestMPVIntegration -v ./...

License

MIT

Documentation

Overview

Package main implements chill, a terminal lofi radio that streams 24/7 lofi beats from YouTube. It uses a client-server architecture where a background daemon manages mpv playback and clients communicate over a Unix socket.

Usage:

chill              # play default station
chill chillhop     # play specific station
chill -i           # interactive mode (repl)
chill --vol 60     # set volume (or +5, -10, up, down)
chill --mute       # toggle mute
chill --status     # show what's playing
chill --stop       # stop playback
chill add n url    # save your own station
chill update       # install the latest release

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL