psysonic-nix
Unofficial NixOS packaging for Psysonic — a Navidrome / Subsonic desktop client built with Tauri (Rust + WebKitGTK).
Files
| File | Purpose |
|---|---|
package.nix |
Main derivation (stdenv.mkDerivation with finalAttrs) |
default.nix |
Local build/test entry-point (nix-build / nix-shell) |
Quick start
# 1. Clone this repo
git clone <your-repo-url>
cd psysonic-nix
# 2. Build
nix-build # produces ./result
# 3. Run
./result/bin/psysonic
allowUnfree = true is set automatically by default.nix.
If you build via NixOS configuration.nix you may need:
nixpkgs.config.allowUnfree = true;
NixOS system installation
Add to your configuration.nix:
{ config, pkgs, ... }:
let
psysonic = pkgs.callPackage /path/to/psysonic-nix/package.nix { };
in
{
nixpkgs.config.allowUnfree = true;
environment.systemPackages = [ psysonic ];
}
Or with a flake overlay — see the Flake usage section below.
Flake usage (optional)
Create a flake.nix alongside package.nix:
{
description = "Psysonic Navidrome client";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
outputs = { self, nixpkgs }: let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; config.allowUnfree = true; };
in {
packages.${system}.psysonic = pkgs.callPackage ./package.nix { };
packages.${system}.default = self.packages.${system}.psysonic;
};
}
Then:
nix build .#psysonic
nix run .#psysonic
AppImage internals & patching strategy
AppImage type
Psysonic ships a type-2 SquashFS AppImage (the standard format used by Tauri's bundler). No DwarFS or custom offsets are needed — appimageTools.extractType2 in nixpkgs handles extraction with unsquashfs automatically.
Why not appimageTools.wrapType2?
wrapType2 mounts the AppImage at runtime via FUSE, which requires the fusermount setuid binary. On NixOS that works but adds friction. Extracting the binary and patching its ELF headers is cleaner and more hermetic.
What gets patched
| What | How |
|---|---|
ELF interpreter (ld-linux) |
patchelf --set-interpreter |
Library search path (rpath) |
patchelf --set-rpath with all runtime deps |
| GIO / TLS modules | GIO_MODULE_DIR env var via makeWrapper |
Desktop entry Exec= line |
substituteInPlace |
Runtime dependencies (Tauri-specific)
Because Psysonic is a Tauri v2 app it links against:
- WebKitGTK 4.1 (
webkitgtk_4_1) — renders the UI - GTK 3 — window chrome, file dialogs
- libsoup 3 — HTTP client used by WebKit
- glib-networking — TLS support for GIO (critical for HTTPS to your Navidrome)
- PipeWire / PulseAudio / ALSA — audio output (the release notes confirm Psysonic prefers PipeWire, then PulseAudio)
- libGL / Mesa — WebKitGTK's WebGL compositor; needed even if the app itself doesn't do 3D
- xdg-utils —
xdg-openfor external links - libxkbcommon + wayland libs — Wayland input/display (Tauri supports both X11 and Wayland natively)
Does the app download additional binaries?
Based on the release notes, Psysonic does not download additional native binaries at runtime. LUFS analysis is done by the bundled Rust binary itself. If a future release bundles a helper binary (e.g. ffmpeg), you will need to patchelf that too — check ${appimageContents}/usr/bin/ after extraction.
OpenGL / Vulkan
WebKitGTK uses libGL for its accelerated compositor. The libGL and mesa entries in buildInputs cover this. You do not need Vulkan for a Navidrome client.
AMD GPU (RX 580)
Your RX 580 uses the open-source amdgpu kernel driver + Mesa radeonsi. NixOS 25.11 enables this by default. No extra configuration should be needed.
Wayland vs X11
Tauri 2 detects WAYLAND_DISPLAY / DISPLAY at startup and chooses accordingly. The wrapper does not force either session type, so the app will work in both.
Troubleshooting
error while loading shared libraries: libwebkit2gtk-4.1.so.0
The rpath patch didn't find the library. Run:
ldd result/lib/psysonic/psysonic | grep "not found"
and add the missing package to buildInputs in package.nix.
App launches but shows a blank white screen
WebKitGTK sandbox issue. Try:
WEBKIT_DISABLE_COMPOSITING_MODE=1 psysonic
or add --set WEBKIT_DISABLE_COMPOSITING_MODE 1 to the makeWrapper call.
TLS / HTTPS errors connecting to Navidrome
glib-networking may not be picked up. Verify:
echo $GIO_MODULE_DIR
ls $GIO_MODULE_DIR # should contain libgiognutls.so or libgiotls.so
Audio device not found
Psysonic prefers PipeWire. Make sure services.pipewire.enable = true in your NixOS config. If you use PulseAudio only, set:
PSYSONIC_AUDIO_BACKEND=pulse psysonic
(or configure in Settings → Audio once the app opens).
Hash mismatch on fetchurl
Re-fetch the hash:
nix-prefetch-url --type sha256 \
https://github.com/Psychotoxical/psysonic/releases/download/app-v1.44.0/Psysonic_1.44.0_amd64.AppImage
Paste the result as sha256 = "..."; in package.nix.
Updating to a new version
- Change
versioninpackage.nix. - Update the
hashusingnix-prefetch-url(see above). - Re-run
nix-buildand verify the app starts.
License
The packaging files in this repository are released under the MIT License. Psysonic itself has its own license — check the upstream repository.