slskr is a self-hosted Rust daemon, HTTP API, and browser UI for the
Soulseek network.
It is built for operators who want a private, scriptable Soulseek client they
can run locally, on a server, or behind their own service boundary. One
slskr serve process owns the Soulseek session, peer listeners, share index,
transfer engine, API, event stream, and bundled Web UI.
slskr is the Rust implementation target for the slskr/slskdN feature-parity
work. The daemon already includes the main operating surfaces needed by a
browser client and API automation:
- Soulseek login/session management, keepalive, reconnect, and listener state.
- Search, browse, private messages, rooms, watched users, shares, and transfers.
- Direct, obfuscated, and indirect peer probes for protocol/runtime validation.
- Bundled Web UI plus compatibility-oriented HTTP endpoints and event streams.
- TypeScript, Python, Go, and Rust client surfaces for automation and tests.
- Release, security, packaging, live-interop, and public-posture gates.
The compatibility goal is behavioral and operational compatibility with useful slskd/slskdN workflows, not a copied implementation. Advanced discovery, metadata, integrations, and mesh/federation surfaces should be treated as configuration-dependent or experimental unless the linked docs and tests say otherwise.
- Screenshots
- Features
- Quick Start
- Configuration
- Security
- HTTP API Examples
- CLI Reference
- Testing And Verification
- Deployment
- Repository Layout
- Documentation Index
- Support
- License
The README screenshots are generated from the local Web UI with mocked daemon responses, so they do not contain credentials.
| Search and discovery | Transfers |
|---|---|
| Rooms and messaging | System status |
|---|---|
Regenerate screenshots from a running frontend with:
cd web
SLSKR_SCREENSHOT_BASE_URL=http://127.0.0.1:3001 \
node scripts/capture-readme-screenshots.mjsslskr serve starts the daemon and serves the Web UI on the same HTTP listener.
The default bind is loopback-only:
http://127.0.0.1:5030/
The UI includes search, downloads, uploads, rooms, private messages, users, contacts, browse state, shares, collections, integrations, player controls, configuration status, telemetry, and runtime health.
Search supports global, user, room, and wishlist-style targets. Results include peer metadata such as locked state, slot availability, queue length, speed, file size, and path. The UI adds filters, duplicate folding, hidden/blocked users, search history, review notes, acquisition profiles, discovery graph panels, and metadata-assisted follow-up searches.
Downloads and uploads are represented as daemon-owned transfer records with
queue, start, progress, completion, cancellation, retry, and failure state.
slskr supports local file-backed projections for tests, outbound downloads,
inbound shared-file serving, direct peer transfer sockets, type-1 obfuscated
transfer sockets, indirect transfer fallback, offset/resume fields, and bounded
transfer event history.
Share roots are indexed at startup or by rescan. The catalog uses virtual share paths rather than exposing raw host paths. Operators can configure hidden-file handling, symlink following, scan limits, and allowed transfer directions. Browse state is tracked per peer and exposed through the API and Web UI.
The daemon tracks private-message conversations, message acknowledgement, room lists, room join/leave state, recent room messages, watched users, user stats, contacts, notes, and related peer context needed by search and browse workflows.
The HTTP API exposes versioned /api/v0/* routes plus selected unversioned
compatibility aliases. API clients can use bearer auth or the X-API-Key header
with the same token. Event consumers can poll bounded event records or subscribe
to the WebSocket event stream.
OpenAPI and detailed endpoint docs live in:
Current integration surfaces include Spotify OAuth callback handling on the daemon HTTP listener, Lidarr status/wanted/manual-import flows, external visualizer launch reporting, and UI-side panels for library, source, and recommendation workflows. Integrations report unavailable or disabled states when required local config or credentials are missing.
Release artifacts are published from tags named release-v<semver>:
https://github.com/snapetech/slskr/releases
Archives include the slskr binary and bundled web assets for supported Linux,
macOS, and Windows targets, plus checksums and release manifests. Extract the
archive for your platform, put the binary on your PATH, then create a config.
Prerequisites:
- Rust toolchain compatible with the workspace
rust-version. - Node.js/npm when working on or testing web assets.
- Soulseek credentials for real network operation.
- Optional Go and Python for client-library test gates.
Build and install locally with the React Web UI used in the screenshots:
npm --prefix web ci
npm --prefix web run build
cargo build --release -p slskr
install -Dm755 target/release/slskr "$HOME/.local/bin/slskr"
mkdir -p "$HOME/.local/share/slskr/web"
cp -R web/build "$HOME/.local/share/slskr/web/build"slskr serve looks for the production UI in SLSKR_WEB_BUILD_DIR, next to the
binary as web/build, under $prefix/share/slskr/web/build, or in the current
repository checkout. / is the full React client when those assets are present.
The minimal built-in operator dashboard is available at /dashboard; if no
built UI is present, / falls back to that dashboard and explains how to install
the full UI.
Print version information:
slskr versionRun a login smoke test:
SLSK_USERNAME=<username> \
SLSK_PASSWORD=<password> \
slskr login smokeStart the daemon and Web UI:
slskr serveThen open:
http://127.0.0.1:5030/
On first connect, the Web UI prompts for Soulseek credentials and lets you choose
runtime-only memory, the platform OS credential store, or a restricted local
credential file. Linux services can use read-only systemd credentials through
LoadCredential= or LoadCredentialEncrypted=. SLSK_USERNAME/SLSK_PASSWORD
and config-file credentials remain supported for container secret managers and
scripted deployments.
Start from the annotated example:
docs/slskr.config.example.toml
Default config path:
$XDG_CONFIG_HOME/slskr/config.toml
Fallback when XDG_CONFIG_HOME is unset:
$HOME/.config/slskr/config.toml
Default state directory:
$XDG_STATE_HOME/slskr
Fallback when XDG_STATE_HOME is unset:
$HOME/.local/state/slskr
Use SLSKR_CONFIG=/path/to/config.toml and
SLSKR_STATE_DIR=/path/to/state to override those paths. Environment variables
override config-file values.
Common settings:
| Setting | Purpose |
|---|---|
SLSKR_HTTP_BIND |
HTTP listener, default 127.0.0.1:5030. |
SLSKR_AUTO_CONNECT |
Connect at startup when credentials are configured or stored. |
SLSKR_CREDENTIAL_STORE |
Soulseek credential storage: os, systemd, memory, or file. |
SLSKR_CREDENTIAL_FILE |
Local credential-file fallback path; default is under SLSKR_STATE_DIR. |
SLSK_USERNAME, SLSK_PASSWORD |
Soulseek account credentials for env/config secret-manager deployments. |
SLSKR_API_TOKEN |
Token for protected API routes. |
SLSKR_SHARE_DIRS |
Semicolon-separated share roots. |
SLSKR_LISTENER_BIND |
Regular peer listener bind address. |
SLSKR_ADVERTISED_PORT |
Public regular peer port advertised to the network. |
SLSKR_OBFUSCATED_LISTENER_BIND |
Optional obfuscated peer listener bind address. |
SLSKR_OBFUSCATED_ADVERTISED_PORT |
Public obfuscated peer port. |
SLSKR_TRANSFER_MAX_ACTIVE |
Maximum active transfers. |
SLSKR_TRANSFER_ALLOW_INBOUND |
Enable inbound shared-file serving. |
SLSKR_TRANSFER_ALLOW_OUTBOUND |
Enable outbound downloads. |
SLSKR_PERSISTENCE_ENABLED |
Enable SQLite-backed persistence paths. |
SLSKR_LOG_LEVEL |
Runtime log threshold: trace, debug, info, warn, or error. |
The Web UI System -> Logs tab can inspect recent daemon logs and change the
runtime log level without a restart. RUST_LOG is still accepted as a familiar
alias, while SLSKR_LOG_LEVEL takes precedence.
See docs/credential-storage.md for credential store tradeoffs and docs/install.md for service units, state layout, container shape, and exposure rules.
Default behavior is intentionally conservative:
- HTTP binds to
127.0.0.1:5030by default. - Non-loopback HTTP binds require
SLSKR_API_TOKENunless auth is explicitly disabled withSLSKR_AUTH_DISABLED=true. - Protected API routes accept
Authorization: Bearer <token>orX-API-Key: <token>. - Browser-origin mutating requests are checked with
Origin/Refererto reduce CSRF exposure. - Sanitized config responses do not return credentials.
- Share APIs return virtual paths rather than raw host paths.
Before exposing slskr beyond localhost, set an API token, keep auth enabled,
put it behind a reverse proxy you control, and make sure forwarded Host,
Origin, and Referer headers are preserved. Peer listener ports are separate
from the HTTP UI/API port and should match the advertised ports configured for
your NAT, VPN, or port-forwarding setup.
Create a search:
curl -H "Authorization: Bearer $SLSKR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"Example sound file Ogg Vorbis","target":"global"}' \
http://127.0.0.1:5030/api/v0/searchesList transfer projections:
curl -H "Authorization: Bearer $SLSKR_API_TOKEN" \
http://127.0.0.1:5030/api/v0/transfersStream events:
curl -H "Authorization: Bearer $SLSKR_API_TOKEN" \
http://127.0.0.1:5030/api/v0/eventsRun the slskd-style API automation smoke:
SLSKR_SLSKD_API_SMOKE_TOKEN=slskd-api-smoke-token \
scripts/run-slskd-api-compat-smoke.shCommon operator commands:
slskr serve
slskr version
slskr login smoke
slskr smoke local-peer
slskr soak live
slskr probe peer-address
slskr probe plain-peer
slskr probe browse-peer
slskr probe search-peer
slskr probe download-peer
slskr probe private-message
slskr probe room-message
slskr probe obfuscated-peer
slskr probe indirect-peer
slskr probe distributed-peer
slskr probe file-transfer-peer
slskr probe metadata-relogin
slskr probe negative-indirectThe probe commands are deliberately narrow. Use them to verify one network behavior at a time before running broader live smoke or soak suites.
Common local checks:
cargo fmt --all --check
cargo test --workspaceWeb checks:
cd web
npm test
npm run buildRelease/package checks:
scripts/check-release-package.sh
scripts/run-release-gate.shLocal two-account peer smoke:
SLSKR_A_USERNAME=<user-a> \
SLSKR_A_PASSWORD=<pass-a> \
SLSKR_B_USERNAME=<user-b> \
SLSKR_B_PASSWORD=<pass-b> \
SLSKR_INDIRECT_HOST_OVERRIDE=127.0.0.1 \
cargo run -p slskr -- smoke local-peerLive interop and soak scripts are under scripts. They use real accounts and public-network behavior, so run them deliberately and provide credentials through your normal local secret source.
slskr is designed around one daemon process, one config file, one state
directory, and explicit operator-controlled secrets.
Deployment assets include:
- Systemd examples in docs/install.md.
- Kubernetes manifests in k8s.
- Prometheus rules and ServiceMonitor examples in k8s.
- Public posture checks in scripts/check-public-posture.sh.
- Release packaging checks in scripts/check-release-package.sh.
For container deployments, run the same command, slskr serve, mount config
read-only, mount state read-write, and expose only the HTTP and peer listener
ports you intend to publish.
.
├── crates/
│ ├── slskr/ # daemon, API, web serving, config, storage, telemetry
│ ├── slskr-client/ # async session, peer, search, browse, transfer runtime
│ ├── slskr-protocol/ # protocol messages, codecs, frames, obfuscation
│ └── slskr-web/ # Rust/WASM web UI migration target
├── web/ # React/Vite Web UI and screenshot/test harness
├── client-ts/ # TypeScript API client
├── client-python/ # Python API client
├── client-go/ # Go API client
├── docs/ # API, install, feature, fixture, and release docs
├── examples/ # example workflows
├── fixtures/ # hash-pinned fixture manifests
├── k8s/ # Kubernetes deployment and observability manifests
└── scripts/ # smoke, soak, posture, release, and fixture helpers
Start with the full documentation map in docs/README.md. The table below links the maintained entry points most users need first.
| Document | Purpose |
|---|---|
| docs/README.md | Full documentation index, status notes, and cross-links. |
| docs/install.md | Build, install, config/state, service, container, and exposure runbook. |
| docs/app-surface.md | User-facing app surface and compatibility map. |
| web/README.md | React Web UI development, audit, build, and screenshot workflow. |
| docs/http-api.md | HTTP API reference. |
| docs/http-api-deployment.md | Deployment notes for the HTTP listener, auth, reverse proxies, and Kubernetes. |
| docs/http-api-features.md | HTTP API capability notes and workflow examples. |
| docs/openapi.json | OpenAPI document. |
| docs/WEBHOOK_API.md | Webhook API and delivery model. |
| docs/CLIENT_LIBRARIES.md | TypeScript, Python, Go, and Rust client notes. |
| client-ts/README.md | TypeScript/JavaScript client package usage. |
| client-python/README.md | Python client package usage. |
| client-go/README.md | Go client package usage. |
| examples/README.md | API and automation examples. |
| docs/live-interop-test-matrix.md | Live network and cross-client verification matrix. |
| docs/open-commons-fixtures.md | Open fixture policy and source list. |
| docs/release.md | Release tag, archive, and metadata policy. |
| COMPLIANCE.md | Public posture, licensing, and project compliance notes. |
| docs/slskr.config.example.toml | Annotated config example. |
Canonical repository:
https://github.com/snapetech/slskr
Community support and migration discussion can be found on Discord: discord.gg/hyG8Pf6KGA.
slskr is licensed under AGPL-3.0-only. See LICENSE and
NOTICE.