Psychotoxical d50c9c444d refactor(settings): reusable SettingsGroup/SettingsToggle + boxed sections across tabs (#1126)
* 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)
2026-06-18 22:24:34 +02:00
2026-06-18 11:19:01 +03:00

Psysonic Logo

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.


Latest Release GitHub Stars License GPLv3 Tauri v2

Discord Community Telegram Community Support Psysonic on Ko-fi

AUR psysonic AUR psysonic-bin Cachix WinGet psysonic



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


Psysonic Screenshot


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

Shared listening feature banner

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=x11 for 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.

Languages
TypeScript 69.9%
Rust 24.9%
CSS 4.3%
JavaScript 0.5%
Shell 0.3%