Getting started

From zero to playing music in two minutes

You'll need a machine running Linux (a Raspberry Pi, some Debian box, whatever) with mpv installed and a folder full of audio files. That's the whole prerequisite list.

Install mpv

On Debian or Raspberry Pi OS:

sudo apt update
sudo apt install mpv

On macOS it's brew install mpv. On Arch, pacman -S mpv. You know the drill.

Get the code

If you just want to run it, install from npm:

npm install -g mpv-web-control
mpv-web-control start

Or build from source:

git clone <repo-url> mpv-web-control
cd mpv-web-control
pnpm install

Node 22 or newer, pnpm 9 or newer. If you're on a Pi and don't have pnpm yet: corepack enable && corepack prepare pnpm@latest --activate.

Build

pnpm build

This compiles the shared contract package, the Hono backend, and the React frontend in one pass. Takes maybe 15 seconds on a Pi 4.

Run it

MUSIC_ROOT=/mnt/my-music pnpm start

The server binds to 0.0.0.0:3000 by default, so anything on your local network can reach it. Open http://<your-pi-ip>:3000 on your phone or laptop.

If mpv isn't already running in the background, the server starts it for you and connects over a Unix socket at /tmp/mpv-web-control.sock.

Deploy to a server

If you're running this on a headless machine (Pi, VPS, whatever) and want it to start on boot, use the packaging script:

# On your build machine:
git clone <repo-url> mpv-web-control
cd mpv-web-control
pnpm install
bash scripts/package.sh

This produces a tarball in dist/. Copy it to the target machine and run the installer:

# On the target machine:
sudo bash scripts/install.sh mpv-web-control-*.tar.gz

The installer creates a system user, extracts everything to /opt/mpv-web-control, installs a systemd service, and writes a config file to /etc/mpv-web-control/env. You need to set MUSIC_ROOT there before starting:

sudo nano /etc/mpv-web-control/env
sudo systemctl start mpv-web-control

To uninstall: sudo bash scripts/install.sh --uninstall.

Development mode

If you're hacking on the code, run the backend and frontend separately:

# terminal 1
MUSIC_ROOT=/mnt/music pnpm dev:server

# terminal 2
pnpm dev:client

The frontend dev server runs on Vite's default port (5173) with hot reload. The backend restarts on file changes via tsx watch.

What's next?