- Your whole library — add any folder and Airmedy scans it instantly, even with tens of thousands of tracks.
- Lyrics that follow along — synced lyrics scroll line-by-line as the song plays. Plain-text lyrics shown when sync data isn't available. Sources, in priority order: local lyric files next to the track (
.lrc, then.txt), embedded lyrics, then online lyrics from LRCLIB and Kugou. - Fullscreen & miniplayer modes — go fullscreen for an immersive listening experience, or shrink to a miniplayer that stays out of your way.
- Playlists — create and manage playlists, import and export them, and browse your collection by genre, artist, or album.
- Gapless playback — tracks transition without any silence or interruption.
- 10-band equalizer — tune the sound to your headphones or speakers. Runs natively on macOS (SFBAudioEngine) and Windows/Linux (miniaudio) for optimal performance.
- Lock screen & media keys — control playback from your keyboard, lock screen, or Control Center — just like a first-party app.
- Last.fm scrobbling — sync your listening history and loved tracks automatically.
- Fast search — find any track, album, or artist in milliseconds.
- Metadata editor — update track titles, artists, albums, and other tags. Support for updating album artwork with automatic JPEG conversion.
- Plays in the background — close the window and music keeps going. Quit when you actually mean it.
- Tray menu — control playback from the system tray.
- Prevent sleep — optionally keep your system awake while music is playing.
- Themes — light, dark (gray), and black (pure black for OLED screens) themes.
- Artist images — uses local
artist.jpg/.jpeg/.pngfiles from your music folders (in the artist folder or beside the songs), or set your own custom image per artist. Toggle "Online Artist Artwork" to use Deezer images instead; turn it off to use your local files. - Remote control — control playback from any browser on the same network. Enable the remote server in settings, open the displayed URL on your phone or tablet, and enter the PIN to start controlling playback, managing the queue, and viewing lyrics remotely.
Every format plays on macOS · Windows · Linux.
| Format | Extensions |
|---|---|
| MP3 | .mp3 |
| AAC / ALAC | .m4a .aac .mp4 |
| FLAC | .flac |
| WAV / AIFF | .wav .aiff |
| Ogg Vorbis | .ogg |
| Opus | .opus |
| APE (Monkey's Audio) | .ape |
| WavPack | .wv |
| DSD | .dsf .dff |
On macOS, playback runs through SFBAudioEngine — a powerful, high-performance audio engine that provides native support for almost every format without needing FFmpeg. On Windows and Linux, miniaudio provides high-performance audio output, while FFmpeg serves as the universal decoding backend for all supported formats, ensuring consistent and robust playback across the entire library.
flowchart TB
subgraph Core["Airmedy Core"]
subgraph macOS["macOS Path"]
SFB["SFBAudioEngine<br/>(All Formats)"]
end
subgraph WinLinux["Windows / Linux Path"]
FF["FFmpeg Decoder<br/>(All Formats)"] --> MA["miniaudio<br/>(output engine)"]
end
SFB --> Stream
MA --> Stream["Consistent Audio Stream<br/>(Float32 PCM)"]
end
The FFmpeg libraries are statically compiled and bundled inside internal/infra/audio/ffmpeg_libs/. No system FFmpeg installation is ever required.
| Layer | Technology |
|---|---|
| Backend runtime | Go 1.25, Wails v3 |
| Dependency injection | uber-go/fx |
| Database | SQLite via golang-migrate |
| Search index | Bleve |
| File watching | fsnotify |
| Audio (macOS) | SFBAudioEngine + CGo |
| Audio (Win/Linux) | miniaudio + FFmpeg (CGo) |
| Metadata | go-taglib |
| Frontend framework | Vue 3 (Composition API) |
| State management | Pinia 3 |
| UI components | Radix Vue + Tailwind CSS v4 |
| Monorepo | pnpm workspaces + Turbo |
| UI package | @airmedy/ui (packages/ui) |
| Utils package | @airmedy/utils (packages/utils) |
| Lyrics | Local .lrc/.txt, embedded tags, LRCLIB + Kugou |
Airmedy follows a Hexagonal / Ports & Adapters pattern:
main.go # Entry point
internal/
├── domain/ # Business logic, interfaces, DTOs
├── app/ # Application services (use cases)
└── infra/
├── audio/ # SFBAudioEngine / miniaudio / FFmpeg adapters
├── db/ # SQLite migrations and queries
├── search/ # Bleve index adapter
└── wails/ # Thin Wails bindings (frontend ↔ app)
frontend/ # Main desktop UI (Vue 3)
├── src/
│ ├── components/ # Feature components (AlbumCard, TrackTable…)
│ ├── views/ # Route-level pages
│ ├── stores/ # Pinia stores
│ ├── composables/ # Shared logic
│ └── locales/ # i18n locale files
packages/
├── ui/ # @airmedy/ui — stateless UI primitives (Slider, Input…)
└── utils/ # @airmedy/utils — shared utilities (logger, utils)
remote/ # Browser-based remote control SPA (Vue 3)
└── src/
├── components/ # Remote UI components
├── stores/ # Pinia stores (player state over WS)
└── locales/ # i18n locale files
Dependencies always point inward — infra depends on app, app depends on domain, never the reverse.
| Tool | Version |
|---|---|
| Go | ≥ 1.25 |
| Node.js | ≥ 20 |
| pnpm | ≥ 9 |
| Task | taskfile.dev |
| Wails CLI v3 | go install github.com/wailsapp/wails/v3/cmd/wails@latest |
No system FFmpeg required. FFmpeg is the decode backend on Windows/Linux only — macOS uses SFBAudioEngine and ships no FFmpeg. Pre-built static libraries for
windows/amd64,windows/arm64,linux/amd64, andlinux/arm64are bundled ininternal/infra/audio/ffmpeg_libs/.To rebuild them:
scripts/build-ffmpeg-linux.shandscripts/build-ffmpeg-windows.sh(the latter cross-compilesamd64+arm64from Linux viagcc-mingw-w64).scripts/build-ffmpeg-windows-msys2.shbuilds Windowsamd64natively inside an MSYS2 MINGW64 shell. All produce minimal static.alibs (FFmpeg 8.1, decoders only).
git clone https://github.com/misa198/airmedy.git
cd airmedy
# Run in development mode
wails3 dev
# Build production binary
wails3 buildwails3 task verify # runs all Go unit tests + Vue component tests + linterswails3 task {task_name}- Smart Playlists — rule-based auto-playlists (genre, BPM, play count)
- AirPlay 2 — stream to any AirPlay speaker or Apple TV directly from Airmedy.
- Fork the repo and create a feature branch
- Follow Conventional Commits — enforced by the
commit-msghook (wails3 task setup:hooks) - All new features and bug fixes require accompanying tests
- Open a pull request against
master
MIT © misa198


