* fix(orbit): kick a fresh playTrack when engine is stuck mid-load Follow-up to #525. Symptom: occasionally on join, the guest gets no audio until the next host-driven track change, at which point a fresh `playTrack` runs and audio plays normally. Root cause: when the initial `syncToHost` poll hits its 5 s deadline without the engine reporting `isPlaying === true` (slow Navidrome cold-start), the next pull tick takes the cheap "track already loaded" shortcut and calls `applyMirror`. `applyMirror` fires `seek` + `resume` on an engine that is stuck in a "loaded but never started" limbo — seek silently no-ops and `resume` can't kick a track that never began. Guest is silent until something else triggers a fresh `playTrack`. Tighten the shortcut: take the cheap path only when the engine is already in the state the host expects (or playing while host is paused, which is fine to align via pause). Otherwise fall through to a fresh `playTrack` and the existing 5 s ready-poll, which re-initialises the engine and lets audio actually start. * docs(changelog): add engine-limbo follow-up bullet * fix(orbit): re-sync when engine silently fell back to paused The optimistic `isPlaying: true` `playTrack` writes synchronously masks a `audio_play` failure: the post-playTrack poll sees the optimistic flag, fires `applyMirror`, and the outer tick records `lastAppliedRef = { ..., isPlaying: true }` as a successful sync. But if the underlying `invoke('audio_play')` rejects later (network blip / cold-start exhaustion), the catch handler flips the flag back to `false` and schedules `next()`, which short-circuits to `audio_stop` in an Orbit guest — leaving the player silent while `lastAppliedRef` still claims we're playing. None of the divergence-detection branches (track-change / play-pause-flip) match, so the guest never re-syncs. Add a recovery check before the if/else-if chain: when the captured `last` says we applied playing, the engine is currently not playing, and the host is still playing the same track, reset `lastAppliedRef.current = null`. The next iteration of the chain re-runs initial-sync (with the 500 ms fast-poll cadence) which fires a fresh `playTrack`. If `audio_play` succeeds the second time, audio finally starts; if it keeps failing, we loop with no extra harm (audio was already silent). Adds an `engine-recovery` event scope to the diagnostics buffer so future captures can see when this re-sync fired. * docs(changelog): expand engine-recovery bullet to cover both cases
A modern desktop client for self-hosted music libraries
Fast. Native. Beautiful. Built for people who actually care about their music collection.
Psysonic is built primarily for Navidrome and also works with Gonic, Airsonic, LMS and other Subsonic-compatible servers, depending on the features supported by your server.
No telemetry • Native performance • Navidrome-first • Community driven
Warning
Psysonic is under active development. Bugs and rough edges can happen, and features may change as the project evolves.
What is Psysonic?
Psysonic is a desktop music client for self-hosted music libraries. It is designed for people who want the freedom of their own server without giving up the comfort, polish and speed of a modern music app.
It is built with Rust, Tauri v2 and React, with a strong focus on responsiveness, customization, practical music-library workflows and a user interface that does not require a manual before you can press play.
Psysonic is optimized first and foremost for Navidrome. Other Subsonic-compatible servers can work well too, but advanced features may depend on server-side support.
Highlights
Playback & Queue
- Gapless playback
- Crossfade
- ReplayGain support
- LUFS-based Smart Loudness Normalization
- AudioMuse-AI support
- Infinite Queue
- Smart Radio sessions
- Fast and responsive playback handling
- Low memory usage compared to heavy web-first clients
Audio Tools
- 10-band Equalizer
- Equalizer presets
- AutoEQ headphone correction
- Per-device optimization
- Loudness-aware playback options
Library Management
- Fast search across large libraries
- Albums, artists, tracks and genres
- Ratings support
- Multi-select bulk actions
- Drag & drop playlist management
- Smart Playlists
- Built for large self-hosted collections
Lyrics & Discovery
- Synced lyrics with seek support
- Lyrics provider support: YouLy+, LRCLIB and NetEase
- Auto-scrolling sidebar lyrics
- Fullscreen lyric mode
- Last.fm scrobbling
- Similar artists
- Loved tracks and listening stats
Sharing & Social Listening
-
Magic Strings sharing:
- share albums, artists and queues
- Navidrome user management helpers
- fast account sharing
-
Orbit shared listening sessions:
- host-controlled synchronized playback
- session invites via link
- guest song suggestions
- real-time queue interaction
Personalization & Accessibility
- Large theme collection
- Catppuccin and Nord inspired styles
- Glassmorphism effects
- Font customization
- Zoom controls
- Keybind remapping
- Theme Scheduler for automatic day/night switching
- Colorblind-friendly theme options
- Keyboard-friendly navigation
Power User Extras
- CLI controls
- USB / portable sync
- Backup and restore settings
- In-app auto updater
- LAN / remote auto switching
Orbit brings synchronized shared listening sessions directly into Psysonic.
Start a session, invite others with a link and listen together with host-controlled playback, shared queue interaction and guest song suggestions. It is built for real-world music sharing without turning your self-hosted setup into a social-media circus.
Platforms
| OS | Support |
|---|---|
| Windows | Native installer |
| macOS | Signed DMG |
| Linux | AppImage / DEB / RPM / AUR (psysonic, psysonic-bin) / NixOS |
Psysonic supports 8 languages and growing.
Install
Linux
curl -fsSL https://raw.githubusercontent.com/Psychotoxical/psysonic/main/scripts/install.sh | sudo bash
Linux builds are also available through GitHub Releases, AUR and Cachix/Nix.
Windows
Download the latest installer from the GitHub Releases.
macOS
Download the signed DMG from the GitHub Releases.
Development
git clone https://github.com/Psychotoxical/psysonic.git
cd psysonic
npm install
npm run tauri:dev
Build release:
npm run tauri:build
Privacy
Psysonic is built for self-hosted music collections. Your library is yours.
- No telemetry
- No spyware nonsense
- No analytics harvesting
- No hidden tracking
Community & Support
Join the community, report bugs, suggest features, share themes and help shape the future of Psysonic.
License
Psysonic is licensed under the GNU GPL v3.0.
Forks and Attribution
Psysonic is free and open-source software under the GPLv3. You are welcome to fork it, modify it and build upon it under the terms of the license.
If you publish a modified or rebranded version, please make it clear that your project is based on Psysonic and preserve proper attribution to the original project.
That is not about preventing forks. Forks are part of open source. It is about being honest with users and contributors about where the work comes from.
Features, design work and implementation ideas developed in Psysonic should not be presented as unrelated original work in downstream projects.
Own your music. Enjoy the client too.
Psysonic brings a modern desktop experience to self-hosted music libraries.

