Skip to content

Contributing

Mattia edited this page Mar 9, 2026 · 1 revision

Architecture Overview

SubTUI follows a clean separation between its terminal UI and audio playback:

┌──────────────────────────────┐
│   Bubble Tea TUI (frontend)  │
│   internal/ui/               │
│                              │
│   ┌────────────────────────┐ │      ┌──────────────────────┐
│   │  Bubble Tea Model      │─┼──IPC─│  mpv (headless)      │
│   │  (state, view, update) │ │      │  --idle --no-video   │
│   └────────────────────────┘ │      │  --gapless-audio=yes │
│                              │      └──────────────────────┘
│   ┌────────────────────────┐ │
│   │  Integrations          │ │
│   │  MPRIS / Discord RPC   │ │
│   └────────────────────────┘ │
└──────────────────────────────┘
  • Frontend - Built with Bubble Tea (Elm-architecture TUI framework) and Lip Gloss for styling. The UI state machine lives in internal/ui/.
  • Backend - A headless mpv process handles all audio decoding and playback. SubTUI communicates with it over a Unix domain socket (/tmp/subtui_mpv_socket_<UID>) using mpv's JSON IPC protocol. See internal/player/player.go.
  • API Layer - internal/api/ handles all Subsonic API communication (search, streaming URLs, scrobbling, playlists, etc.).
  • Integrations - internal/integration/ contains MPRIS (Linux/FreeBSD via D-Bus) and Discord Rich Presence support.

Contributing

Contributions are welcome! Here's how to get started:

Setting Up

git clone https://github.com/MattiaPun/SubTUI.git
cd SubTUI
go build .
./subtui

SubTUI uses Go modules. The build embeds the default config.toml and credentials.toml files via //go:embed directives, so no external config files are needed at compile time.

Commit Messages

This project uses Conventional Commits. All commit messages must follow this format:

<type>(<scope>): <description>

Examples:

  • feat(ui): add album art to player footer
  • fix(player): handle mpv socket timeout
  • chore(nix): update vendorHash

Linting

You can lint your changes locally before submitting a PR:

golangci-lint run

Build Tags

  • Linux / FreeBSD - Full build including MPRIS/D-Bus support.
  • macOS (Darwin) - MPRIS is stubbed out; all other features work normally.

Workflow

  1. Fork the project
  2. Create your feature branch (git checkout -b feat/AmazingFeature)
  3. Make your changes and lint them with golangci-lint run
  4. Commit using conventional commit messages
  5. Push to your branch (git push origin feat/AmazingFeature)
  6. Open a Pull Request

Clone this wiki locally