A Compose Multiplatform desktop music client for OpenSubsonic / Navidrome — companion to the Neiro Android app.
Dynamic album-art color theming, Last.fm scrobbling, and one-click sync to Rockbox DAPs.
- Color palette extracted from the current album art and applied across the whole UI
- Animated transitions between palettes on track change
- Full light / dark mode toggle in settings
- When browsing an album or artist, the sidebar and chrome pick up that artwork's colors
- Or pin a fixed accent color instead — preset swatches or any hex value, in Settings → Appearance
- Streams directly from your OpenSubsonic/Navidrome server — no downloads, no local library
- VLC-backed player (vlcj) for broad format support
- Seek bar with real-time position, volume control, shuffle, and repeat (one/all)
- Queue panel in the fullscreen Now Playing view
- Auto-advance to next track; previous track restarts within 3 s
- Fullscreen immersive player: blurred album art background + dark/light overlay
- Queue sidebar with currently playing indicator
- Love track directly to Last.fm from the player
- Configurable sections: Recently Added, Random, Highest Rated, Frequent, Most Recently Played
- Last.fm Top Albums, Top Artists, Top Tracks — all cross-referenced with your Subsonic library
- Configurable time range (7 days / 1 month / 3 months / 6 months / 1 year / all time)
- Scrobble counts shown on album cards
- Click any Last.fm item to navigate directly to the matching album or artist
- Automatic "Now Playing" update on every track start
- Scrobbles at the standard threshold: ≥ 30 s played and ≥ 50 % of track length (or 4 min)
- Personal scrobble counts per artist's top tracks (your history, not global charts)
- Love / unlove tracks from the Now Playing screen
- Full OAuth login from the desktop settings screen
- Albums, Artists, Playlists — all paginated and searchable
- Artist detail: biography, top tracks with your personal scrobble counts, album grid
- Album detail: full track list, total duration, play count, scrobbles badge
- Browser: iTunes-style artist/album browser with keyboard typeahead jump-to-artist and inline expandable tracklists, grouped by year
- Collapsible sidebar with search built in, and a dedicated queue panel next to the player showing the current track's format/bitrate/genre
- Generate a QR code in settings → scan with the Neiro Android app
- Transfers server URL + credentials to the phone in one step; no manual typing
The desktop app includes a full sync engine for Rockbox DAPs (and any mounted folder).
Sidebar → Device Sync
| Setting | Options |
|---|---|
| Device path | Any mount point, e.g. /media/user/ROCKBOX |
| Folder template | Configurable with {artist}, {album}, {track:02d}, {title}, {year} |
| Format | Original · MP3 · OGG Vorbis · Opus |
| Bitrate | 128 / 192 / 256 / 320 kbps |
| Lossless-only conversion | Convert only FLAC/WAV/ALAC; copy lossy sources as-is |
| Playlists | Sync all Subsonic playlists as M3U files to {device}/Playlists/ |
| Cover art | Save as folder.jpg per album directory |
How it works:
- The engine pages through your entire Subsonic library (all albums → all tracks), fetching album metadata with bounded concurrency for speed
{albumArtist}is resolved once per album from the album's own artist field — never per track — so a record can't scatter across multiple artist folders because of inconsistent tags- Each track's destination path is computed from the folder template and file extension; downloads run with bounded concurrency too
- A sync manifest tracks which format/bitrate each file was last synced with, so changing your conversion settings correctly re-syncs the affected files instead of silently skipping them — or force a full re-sync with one checkbox
- Transcoding is handled server-side by Subsonic's
stream?format=ogg&maxBitRate=192— no local FFmpeg required - After music sync, all Subsonic playlists are written as M3U with relative paths (directly playable by Rockbox)
- A live progress bar shows:
current track · N/total · ✓synced · ⤳skipped · ✗errors
Tip for Rockbox devices with limited/uncertain codec support (e.g. Innioasis Y1): OGG Vorbis is the safest universally-compatible lossy format — Opus isn't reliably supported by every stock DAP firmware, even where Rockbox itself would play it fine.
Rockbox writes offline plays to a .scrobbler.log file at the device root. Neiro can import it directly:
- Auto-detects the log path from your configured device path
- Parses the standard AUDIOSCROBBLER format, skipping tracks Rockbox marked as skipped (rating
S) - Submits in batches of 50 to Last.fm
- Only clears/archives the log once every entry is confirmed submitted — a partial failure leaves it untouched so nothing is lost on retry
| Language | Kotlin 2.2 |
| UI | Jetpack Compose (Compose Multiplatform Desktop 1.8) |
| Audio | vlcj 4.8 (VLC bindings for JVM) |
| HTTP | Ktor Client 3.0 (CIO engine) |
| Serialization | kotlinx.serialization JSON |
| Image loading | Coil 3 + Ktor network backend |
| Color extraction | Coil + Palette (Swing/AWT fallback) |
| Preferences | JSON file at ~/.config/neiro/prefs.json |
| Build | Gradle 9, compose.desktop plugin, AppImage + Deb packaging |
- JDK 23+
- VLC installed on the system (vlcj requires native VLC libraries)
- A running Navidrome or any OpenSubsonic-compatible server
git clone https://github.com/FabianZettl/NeiroDesktop.git
cd NeiroDesktop
./gradlew run./gradlew createDistributable # → build/compose/binaries/main/app/neiro/
./gradlew packageAppImage # → build/compose/binaries/main/appimage/
./gradlew packageDeb # → build/compose/binaries/main/deb/Last.fm integration (scrobbling, top charts, love/unlove) needs your own free API key — the project doesn't ship one. Create one at last.fm/api/account/create, then either:
- set env vars
NEIRO_LASTFM_API_KEY/NEIRO_LASTFM_API_SECRET, or - create
~/.config/neiro/lastfm.properties:apiKey=your-api-key apiSecret=your-api-secret
Without this, the app runs fine — Last.fm features are just unavailable.
On first launch the setup screen prompts for server URL, username, and password. Credentials are stored locally at ~/.config/neiro/prefs.json. Last.fm login is optional and configured separately in Settings.
The Neiro Android app is the mobile counterpart — same server, same Last.fm account, same playlists. Use the QR sync feature to pair them instantly.
This project was built with significant assistance from Claude (Anthropic) as a coding collaborator — architecture decisions, UI layout, and feature implementation were developed interactively. All code is reviewed and owned by the maintainer.
MIT