* refactor(settings): extract reusable SettingsGroup component
Pull the boxed sub-section pattern (bordered panel + accent uppercase
header) introduced for the Audio tab into a reusable <SettingsGroup
title desc> component, and migrate NormalizationBlock and
PlaybackBehaviorBlock onto it. No visual change.
* feat(settings): box the System behavior section into groups
Split the System -> App Behavior card (which bundled tray toggles, Linux
rendering tweaks and the clock format) into titled SettingsGroup panels
(Tray / Linux rendering / Clock) for a clearer, consistent boxed look.
Adds the group titles across all 9 locales.
* feat(settings): box Appearance visual options; optional SettingsGroup title
Split the Appearance -> Visual options card into a Display group and a
Window group (Linux custom titlebar controls). SettingsGroup now allows an
optional/omitted title for plain boxed panels. Group titles added across
all 9 locales.
* feat(settings): box Discord cover source and templates
Group the Discord cover-source toggles and the activity templates into
separate SettingsGroup panels (templates reuse their existing title/desc),
dropping the manual indent and inline header. No new strings.
* feat(settings): box the Music Network section
Give the scrobble-master toggle, the enrichment-primary picker and the
provider list each a boxed SettingsGroup with an accent header, and switch
the add-a-service provider rows to the boxed panel style for consistent
contrast with the rest of settings.
* feat(settings): titled boxes for Integrations sections + cover source label
Wrap the Discord enable toggle, the Discord cover-source picker (now with a
"Cover art source" title and explainer), Bandsintown and Show-in-Now-Playing
in titled SettingsGroup panels so each single-item section gets the same
accent-headed boxed look. New cover-source strings across all 9 locales.
* feat(settings): box Lyrics tab sections
Wrap the lyrics-sources customizer and the sidebar-style picker in titled
SettingsGroup panels (reusing the existing section titles).
* refactor(settings): consistent content inset in SettingsGroup
Add a body wrapper with a small left inset so every boxed section indents its
controls uniformly (title stays flush at the box edge). Defined once in the
component instead of per section.
* feat(settings): box Storage tab sections incl. cover art cache
Wrap media directory, cover art cache strategy, next-track buffering and
downloads in titled SettingsGroup panels (reusing existing section titles);
align the cover-cache table's first column flush with the new content inset.
* feat(settings): box Library tab, relocate Lucky Mix, add SettingsToggle
- Add a reusable SettingsToggle component for the repeated label/desc/switch row.
- Box the Random Mix blacklist (grouping built-in keywords with the custom
filter), Ratings and the Analytics strategy section.
- Move the "Show Lucky Mix in menu" toggle out of the blacklist and up next to
split-mix navigation and now-playing-at-top in the sidebar customizer.
* feat(settings): box remaining Appearance sections
Wrap library grid, UI scale, font and seekbar style in titled SettingsGroup
panels (reusing the existing section titles).
* feat(settings): box System language, logging and backup sections
Wrap language and logging in titled SettingsGroup panels, and rework the
backup section to drop its redundant inline header (the subsection already
provides it) and box its content. About / Contributors / Licenses stay as
free display content.
* feat(settings): box remaining Audio sections
Wrap Hi-Res, equalizer, playback speed, audio output device and track
previews in titled SettingsGroup panels (reusing the existing section titles).
* feat(settings): box Input tab keybinding sections
Wrap the in-app and global shortcut lists in titled SettingsGroup panels.
* feat(settings): box the Personalisation tab
Convert every customizer (sidebar, home, artist, queue toolbar, playlist,
player bar) to plain inner containers and wrap each in a titled SettingsGroup,
so the boxed look is consistent without nested cards. Box the queue display
mode picker too.
* feat(settings): box the Themes sections above the store
Add a boxed option to the flat Themes sections and apply it to Your Themes,
Auto-Switch Theme and Import (the theme store stays unboxed). Drop the inner
settings-card from InstalledThemes, ThemeImportSection and the scheduler so
the SettingsGroup is the only frame.
* fix(settings): give the Themes boxes a card carrier and accent header
The flat Themes sections had no settings-card behind them, so the bg-app
SettingsGroup had no contrast against the page. Box each above-store section
as settings-card > titled SettingsGroup (accent header) like the rest.
* fix(settings): clean up the server library sync status line
Collapse the offline status to a single icon + phrase ("Server offline —
sync deferred") instead of a redundant "Deferred" badge alongside it, and
drop the now-unused string across all 9 locales.
* fix(queue): keep toolbar toggle buttons coloured active while hovered
The generic .queue-round-btn:hover rule outweighed .active in specificity, so
an active button kept the hover colour until the pointer left — the toggle
only looked on after moving the mouse away. Add an explicit active-hover rule
(mirroring the mini player) so active wins immediately on click.
* fix(settings): fix Lyrics triple title, drop dead Discord cover keys
- Remove LyricsSourcesCustomizer's own section header (the subsection already
titles it) and make its inner cards plain; the Lyrics boxes are now title-less.
- Drop the dead discordCoverSource/discordCoverSourceDesc i18n keys (superseded
by discordCoverTitle/Desc) and un-jam the libraryIndexServer status line in
all 9 locales.
* refactor(settings): drop redundant group titles and double frames
Single-group sections duplicated the subsection title in the group header — make
those groups title-less so the subsection header is the only title. A card whose
sole child is one group now collapses via CSS so single-group sections render a
single frame (matching the card-less Lyrics layout) instead of a card-in-group
double border. Multi-group cards keep their frame as the grouping container.
* fix(settings): keep the flat Themes cards framed when collapsing single-group cards
The single-group card collapse also flattened the Themes section cards, which —
not being inside an accordion — are themselves the contrast surface. Exclude
.themes-section descendants from the collapse.
* refactor(settings): use SettingsToggle for Appearance and System toggle rows
Replace the hand-rolled toggle-row markup in the Appearance visual options and
System tray/Linux/changelog rows with the shared SettingsToggle component, and
extend it with a searchText prop and ReactNode descriptions for the remaining
call sites.
* refactor(settings): roll SettingsToggle out to Integrations, Audio and Storage
Replace hand-rolled toggle rows in the Discord/Bandsintown/Now-Playing,
Hi-Res, hot cache and playback behaviour/rate sections with SettingsToggle.
Make its label optional (desc-only rows whose title is the group header) and
add searchText/id pass-throughs.
* refactor(settings): use SettingsToggle for the remaining standard toggle rows
Track previews master, sidebar lyrics style, YouLyPlus/static-only, queue
display mode and the sidebar split-nav/now-playing/lucky-mix rows now use the
shared component. Genuinely custom rows (drag lists, the skip-star threshold,
the AudioMuse row with its inline link, the fine-step advanced badge) stay
hand-rolled.
* fix(settings): drop duplicate titles on Hi-Res/Bandsintown/Now-Playing, un-jam locale line
These single-toggle sections kept a group title identical to their subsection
header; once the single-group card collapses the title rendered twice stacked.
Make them title-less (the subsection header is the label). Also split the
discordCoverTitle locale entry onto its own line in all 9 locales.
* feat(settings): restore section icons in boxed Themes headers
SettingsGroup gained an optional accent icon slot rendered before the
title; ThemesTab forwards the Palette/Clock/Upload icons the boxed
sections lost when they moved off the bespoke <h2> header.
* style(settings): re-indent SettingsGroup children to nesting level
Pure whitespace: children wrapped in SettingsGroup were left at their
pre-wrap indent. No content change (git diff -w is empty).
* fix(settings): clarify Native Hi-Res Playback description
The old copy led with the disabled-state behaviour ("forces 44.1 kHz"),
which read as if the toggle itself locked output to 44.1 kHz. Describe
what enabling actually does: play each track at its native sample rate
(reconfiguring the output device to match) instead of resampling to
44.1 kHz. Updated across all 9 locales.
* docs: changelog + what's-new for the settings layout refactor (#1126)
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.
Available languages: English, German, Spanish, French, Norwegian Bokmål, Dutch, Romanian, Russian and Chinese.
More translations are added over time.
No telemetry • Native performance • Navidrome-first • Community driven
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 / WinGet |
| macOS | Signed DMG |
| Linux | AppImage / DEB / RPM / AUR (psysonic, psysonic-bin) / NixOS |
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.
AppImage runs under X11/XWayland — it pins
GDK_BACKEND=x11for a stable WebKitGTK stack. For a native-Wayland launch, use the.deb,.rpm, AUR, or Nix packages, which follow your session's display server.
Windows
Download the latest installer from the GitHub Releases.
or,
install via Windows Package Manager (WinGet):
winget install Psysonic
macOS
Download the signed DMG from the GitHub Releases.
Development
Contributor expectations (PRs, CI, Tauri boundary, UI): CONTRIBUTING.md.
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
See TELEMETRY.md for the telemetry stance and PRIVACY.md for how each opt-in integration handles data.
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.

