All apps · 0 apps
libsync
Docker app from JPDVM2014's Repository
Overview
Readme
View on GitHubLibsync
A self-hosted web UI for managing and downloading your Qobuz and Tidal music libraries.
Runs as a small FastAPI + SvelteKit server in Docker (or locally) and is accessed through any browser. It syncs your streaming-service favorites into a local database, lets you search and trigger downloads with live progress, and organizes the files on disk with your preferred folder/track templates. Both Qobuz and Tidal go through standalone async Python SDKs (consumed as a git submodule) — no CLI, no TOML config, no hidden state.
Libsync started life as a fork of nathom/streamrip and was rebuilt around a web UI. The original
ripCLI, the TUI, and the Deezer/SoundCloud source clients are no longer part of this project. See Acknowledgements for credit to the upstream. Some internals (env var names, the on-disk SQLite filename, the.streamrip.jsonsentinel) still carry the old name to preserve compatibility with existing deployments — those will rename in a future major release.
Features
- Library browsing — every album you've favorited in Qobuz or Tidal, with cover art, sortable table, and search
- Album detail — full track list, bit-depth / sample-rate / codec info, per-track download status
- Search — queries the streaming services directly; results show whether each album is already in your library
- Downloads — queue albums from the library or search, with real-time per-track progress pushed over WebSocket
- Playlists — browse Qobuz playlists and queue all referenced albums from a playlist detail panel
- Sync — manual refresh or scheduled auto-sync to keep local library in step with the streaming service
- Custom paths — folder/track format templates with live preview in Settings (
{albumartist},{title},{container},{bit_depth},{sampling_rate}, etc.) - Filesystem dedup — a
.streamrip.jsonsentinel file per album folder so re-scans and reset-database operations don't re-download work you already have - Library scan — fuzzy-matches pre-existing local collections against your synced library (bit-depth-aware, read-only-mount friendly) with a review UI for ambiguous cases and a manual Mark as downloaded button on album pages
- Artwork embedding — cover art baked into tags at configurable resolution
- OAuth login for Qobuz and Tidal (browser/device flows, including a headless URL-paste flow for Qobuz)
- Per-source dedup database so Qobuz and Tidal track IDs never collide
Requirements
- Docker (recommended) — everything runs inside the image, you just need a folder to mount for music and a volume for the SQLite data
- or Python 3.10+, Node 20+,
poetry,ffmpeg, and access toarthursoares/qobuz_tidal_api_clientfor the SDK submodule
A premium Qobuz or Tidal subscription is required for downloads. This project doesn't bypass DRM or account restrictions — it uses your own credentials against the streaming services' own APIs.
Quick start — Docker
# clone with submodules so the Qobuz + Tidal SDKs come along
git clone --recursive git@github.com:arthursoares/libsync.git
cd libsync
# build
docker build -f docker/Dockerfile -t libsync .
# run — mount your music folder and a data volume for the SQLite DB
# (env var and volume names retain the legacy `streamrip` prefix for
# now to keep existing installations working — see top-of-README note)
docker run -p 8080:8080 \
-v ~/Music:/music \
-v streamrip-data:/data \
-e STREAMRIP_DB_PATH=/data/streamrip.db \
libsync
Open http://localhost:8080 and follow the first-time setup below.
If you forgot --recursive, you can initialize the submodule after the fact:
git submodule update --init --recursive
Using Docker Compose
Prefer compose? A ready-to-use file is at docker-compose.example.yml. It pulls the published image from GHCR — no clone, no local build:
curl -O https://raw.githubusercontent.com/arthursoares/libsync/main/docker-compose.example.yml
docker compose -f docker-compose.example.yml up -d
Config, credentials, and the library database land in ./data next to the compose file — back that directory up to preserve your setup. Downloaded music goes to ./music; edit the volume mapping if you want it elsewhere.
The :latest tag tracks stable releases. Swap to :main or :dev if you want rolling branch builds.
Quick start — local dev
git clone --recursive git@github.com:arthursoares/libsync.git
cd libsync
# install backend deps + both SDKs from the submodule
make deps
poetry install
# install frontend deps
cd frontend && npm install && cd ..
# build frontend + run backend with hot-reload on :8080
make dev
Separate targets if you want more control:
make dev-backend— backend only, assumesbackend/static/already has a built frontendmake dev-frontend— frontend only with Vite hot-reload, proxied to a running backendmake test— unit tests (no credentials needed; ~1s)make lint— ruff check onbackend/cd frontend && npm run check— Svelte typecheck / diagnosticsnode --test frontend/tests/*.test.js— lightweight frontend logic testsmake docker— build and run the Docker image
First-time setup
- Open http://localhost:8080 → Settings.
- Qobuz — click Login with Browser to run the OAuth flow. On a remote/headless host, use Headless Login instead: run the flow on a machine with a browser, copy the redirect URL, paste it into the box.
- Tidal — click Connect Tidal to start the device-code OAuth flow. The Settings page opens the approval URL and polls automatically until authorization completes.
- Set Download Path to
/music(Docker) or your preferred local path. - Choose your Qobuz Quality tier and adjust folder / track format templates if needed. The Settings page has a live preview.
- Optional: use Scan Downloads to reconcile any existing music collection on disk with the library. Fuzzy-matches
Artist/Album/folders by tags + bit-depth, auto-marks exact matches, and surfaces ambiguous cases for manual confirmation. For read-only mounts (NFS/SMB), turn Write sentinel file off before running. - Click Save.
- Go to Library → Refresh Library to pull in your favorites.
Architecture (one-paragraph version)
backend/ is a FastAPI app serving both a REST API and a WebSocket channel. frontend/ is a SvelteKit app compiled to static HTML/CSS/JS and served by the backend. State lives in a single SQLite database (backend/models/database.py) — albums, tracks, config, sync history. Streaming-service access goes through arthursoares/qobuz_tidal_api_client, consumed as a git submodule at sdks/qobuz_api_client/, which provides two separate Python packages: qobuz and tidal. Each exposes an AlbumDownloader with progress callbacks that the backend wires to WebSocket events. There is no CLI, no TOML config file, no hidden process — everything the app does is controlled from the Settings page and persisted in the SQLite DB.
For more detail see docs/WEB_UI.md, frontend/README.md, and CLAUDE.md.
Repo layout
libsync/
├── backend/ FastAPI app (REST + WebSocket)
│ ├── api/ Route modules (library, downloads, sync, auth, config, websocket)
│ ├── services/ Library, download, sync services wiring the SDKs to the DB
│ ├── models/ SQLite schema + Pydantic request/response models
│ └── main.py create_app factory + lifespan
├── frontend/ SvelteKit app
│ └── src/lib/ Components, stores, API client, design system
├── sdks/
│ └── qobuz_api_client/ Git submodule: qobuz + tidal Python SDKs
├── tests/ Pytest suite covering backend services, API routes, database
├── docker/Dockerfile Multi-stage build (Node → Python)
├── docs/WEB_UI.md Full architecture + API reference
├── CLAUDE.md Architecture notes for AI assistants working in the repo
├── Makefile Dev/test/build/run targets
└── pyproject.toml Poetry, 3.0.0, backend-only
Contributing
Bug reports and PRs are welcome. Please run make test and make lint before opening a PR. For non-trivial changes, open an issue first so we can agree on the approach.
Acknowledgements
The original nathom/streamrip — this fork started from there and inherited the Qobuz/Tidal client logic, the tagging helpers, and the MQA decryption primitives. Most of that code now lives in the standalone qobuz_tidal_api_client SDK, but the design and much of the hard-won protocol knowledge came from upstream. Thanks to nathom, Vitiko98, Sorrow446, DashLt, and the projects that inspired streamrip in the first place:
Disclaimer
This software is for personal use with your own legitimately-purchased streaming subscriptions. You are responsible for complying with the terms of service of Qobuz and Tidal. The authors take no responsibility for how you use it.
License
GPL-3.0-only, same as the upstream nathom/streamrip project.
Install Libsync on Unraid in a few clicks.
Find Libsync in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.
Categories
Related apps
Explore more like this
Explore allDetails
ghcr.io/arthursoares/libsync:latestRuntime arguments
- Web UI
http://[IP]:[PORT:8080]/- Network
bridge- Shell
sh- Privileged
- false
- Extra Params
--user 99:100
Template configuration
- Target
- 8080
- Default
- 8080
- Value
- 8080
Where downloaded music is stored.
- Target
- /music
- Target
- /data
- Default
- /mnt/user/appdata/libsync
- Value
- /mnt/user/appdata/libsync
- Default
- /data/streamrip.db
- Value
- /data/streamrip.db