Keep your Plex music library in sync with Spotify — automatically, in lossless FLAC.
On the author's own server, Plexify has reached 86% coverage of 2,420 Liked Songs (~142 hours of music) — filled in automatically as lossless FLAC.
Plexify mirrors your Spotify playlists and Liked Songs into Plex, then quietly fills the gaps: it finds the songs you've saved but don't own yet, acquires them as FLAC, tags and files them the way Plex expects, and keeps everything organized. It has a polished web UI (and an optional native macOS app), a first-run setup wizard, and a background engine that just keeps your library complete.
Important
Read this first. Plexify can acquire music from peer-to-peer and mirror sources. It is a personal library tool — you are responsible for how you use it, and you must have the legal right to any music you download. On first run you must accept an agreement to that effect before any downloading is enabled (enforced in the engine, not just the UI). Publishing or using this does not grant you any rights to copyrighted material. See Legal.
A fully native SwiftUI front-end (dark, OLED-black) — same engine, JSON API, and features as the web UI.
| Dashboard | Library |
|---|---|
![]() |
![]() |
Served by the engine — everything the native app does, in the browser.
| Dashboard | Library |
|---|---|
![]() |
![]() |
- Spotify ⇄ Plex playlist sync — two-way, snapshot-aware; your playlists live in both places and stay in order.
- Liked-Songs library autofill — the songs you've saved on Spotify but don't have in Plex get acquired in FLAC and filed automatically.
- Multi-source acquisition — Soulseek (P2P), squid.wtf (Qobuz hi-res), SpotiFLAC (Qobuz/Tidal/Deezer/Amazon mirrors), and Telegram — all optional, tried in your configured order, with per-source blacklisting on bad results.
- Album completion & quality upgrades — fills partial albums and re-acquires lossless tracks at hi-res when available.
- Un-star to replace — 5★ every placed track in Plex; un-star a wrong one and Plexify re-acquires the correct copy from a different source (opt-in).
- Audiobooks — the same drop folder takes books: folders of mp3s are merged into chapterized m4bs (auto-m4b), matched against Audible with a confidence gate that never guesses, tagged via Audnexus (cover, narrator, summary — the edition is picked by matching runtime to your file, so narrators come out right), and filed into a separate Plex library. Low-confidence books wait in a review queue; the app has a cover-art shelf with sorting and soft-delete.
- A real UI — a fast web dashboard (library, playlists, jobs, live activity) plus an optional native macOS app.
- Runs itself — a scheduler handles syncing, acquisition, organization, Plex reconciliation, and hygiene in the background.
Plexify is a Python (Flask + APScheduler) engine that talks to your Plex server and the Spotify Web API, backed by SQLite. The engine decides what to acquire, downloads it, and organizes everything, on a schedule — so it needs to be running for anything to happen. Optionally, a separate downloader daemon (same Docker image) can do the downloading instead, for setups where the engine is not next to the storage. The web UI is served by the engine; the native macOS app is an optional front end onto the same JSON API.
Spotify ⇄ [ Plexify engine + web UI ] ⇄ Plex
│
▼
[ downloader daemon ] → Soulseek / squid.wtf / SpotiFLAC / Telegram
| Thing | Required? | Notes |
|---|---|---|
| Plex Media Server | Yes | You almost certainly already run one. Plexify reads + writes playlists and files FLACs into a library folder. |
| Spotify Developer app | Yes | Free, ~2 minutes — you use your own credentials. See Connecting Spotify. |
| Docker + Docker Compose | Recommended | The easiest way to run it. |
| An SSD for Plexify's data dir | Strongly recommended | DATA_DIR holds a SQLite database in WAL mode that is written constantly. Put it on an SSD/NVMe, not a spinning disk — on an HDD its small random writes queue behind your media reads, which shows up as Plex stuttering during playback. The music library itself is fine on spinning disks; it is only the database that needs the SSD. |
| slskd (Soulseek) | Optional | A Soulseek source. Without it you can still use the other sources. |
| Lidarr | Optional | Album organization / quality management. |
| Telegram account | Optional | Enables the Telegram source. |
| auto-m4b + Audnexus agent | Optional | Only for audiobooks — see Adding audiobooks. |
Setting Plexify up takes about 15 minutes, and you only do it once. Here's the whole picture before you start:
- Install it with Docker (one command, below).
- Open the web page it serves and let the setup wizard connect your Spotify and Plex.
- Turn on any download sources you want (all optional).
You don't need to touch the code. The only file you edit is a short settings file called .env,
and the wizard handles the rest in your browser.
Before you begin, have these ready:
- Docker Desktop installed and running (get it here) — this is what runs Plexify.
- Your Plex server already set up with a music library.
- A Spotify account (free is fine).
Open a terminal and run these three lines (this downloads Plexify and creates your settings file):
git clone https://github.com/<you>/plexify.git
cd plexify
cp .env.example .envOpen the new .env file in any text editor. You only need to set three things — the rest
have sensible defaults you can ignore for now:
| Setting | What to put | How to find it |
|---|---|---|
MUSIC_DIR |
The full path to the folder where Plex keeps your music | In Plex: Settings → your Music library → Edit → Folders. Copy that folder path. |
DOWNLOADS_DIR |
Any empty folder Plexify can use as a workspace for downloads-in-progress | Make a new folder anywhere with space, e.g. /Users/you/plexify-downloads, and paste its path. |
PUBLIC_BASE_URL |
The web address you'll open Plexify at | Leave it as http://localhost:8787 if you'll use Plexify on this same computer. Only change it if you'll open it from another device (then use http://<this-computer's-ip>:8787). |
Example of a filled-in .env (just those three lines):
MUSIC_DIR=/Volumes/Media/Music
DOWNLOADS_DIR=/Volumes/Media/plexify-downloads
PUBLIC_BASE_URL=http://localhost:8787Why
PUBLIC_BASE_URLmatters: Spotify sends you back to this exact address after you log in, so it has to be the address you're actually using.localhostonly works if you're setting up on the same computer that's running Plexify.
Back in the terminal, run:
docker compose up -d --buildThe first run takes a few minutes while it builds. When it finishes, open
http://localhost:8787 (or whatever you set PUBLIC_BASE_URL to) in your browser.
You'll see a setup wizard. It walks you through connecting Spotify and Plex and accepting the usage agreement — the next two sections explain each step. Once you finish it, Plexify starts filling in your library on its own.
The wizard will ask for a Spotify Client ID and Client Secret. These are free and take about two minutes to create — they let Plexify read your playlists and Liked Songs (you're using your own credentials, nothing is shared).
- Go to the Spotify Developer Dashboard and log in.
- Click Create app. Give it any name and description (e.g. "Plexify").
- In the Redirect URI box, paste your Plexify address followed by
/auth/spotify/callback. If you kept the default, that's exactly:(If you changedhttp://localhost:8787/auth/spotify/callbackPUBLIC_BASE_URL, use that address instead — it must match exactly, or Spotify will refuse to connect.) - Save the app. Spotify shows you a Client ID and, behind a "View client secret" link, a Client Secret. Copy both into the wizard's Spotify step.
The wizard finds Plex servers on your network automatically. It needs two things:
- Which Plex server — usually auto-filled; otherwise paste your server's address.
- A Plex token — a short access code that proves it's your server. Here's the official guide to find your Plex token (it takes about a minute).
Then pick your music library from the dropdown, and you're done. Plexify begins syncing your playlists and finding missing songs.
Out of the box, Plexify can find music through squid.wtf, a public source that needs no setup. You can add more sources for better coverage — each is optional and independent:
- Soulseek (peer-to-peer) — the most reliable source for hard-to-find tracks. To use it, open
docker-compose.ymland remove the#marks in front of theslskdservice block, restart withdocker compose up -d, then in Plexify's Settings set the Soulseek URL tohttp://slskd:5030. - Telegram — enable it in Settings by pasting an
api_idandapi_hashfrom my.telegram.org. - Lidarr — if you already run Lidarr for album management, uncomment
the
lidarrservice indocker-compose.ymland point Plexify athttp://plexify-lidarr:8686in Settings.
You can turn these on any time later — you don't have to decide now.
Plexify can organize audiobooks too, into their own Plex library. Music and audiobooks share one drop folder — you just drop a book in and Plexify figures out the rest (a single file, a folder of MP3 chapters, whatever) — it merges the chapters into one file, matches it against Audible for the cover, narrator, and description, and files it away.
To turn it on:
- In
docker-compose.yml, remove the#marks in front of theauto-m4bservice block (this is the piece that stitches multi-file books into one). Restart withdocker compose up -d. - In Plex, install the Audnexus metadata agent (it fetches audiobook covers and details), then create a new Music-type library called "Audiobooks" that uses it. Plexify's Settings → Audiobooks page has a button that creates this library for you.
- Flip on Settings → Audiobooks and choose that library.
If Plexify isn't sure which book a file is, it waits in a review queue on the Audiobooks page so it never guesses wrong — you confirm it with one click, pick from suggestions, or type the title yourself. Deleting a book just moves it to a recoverable trash folder; nothing is ever permanently erased. For the deeper details, see docs/AUDIOBOOKS.md.
Run the engine on the machine that holds your music, and leave it running. That is the whole recommendation. Everything else — the web page, the macOS app — is just a window onto it.
Put its data directory on an SSD. The engine keeps a SQLite database (WAL mode) that it
writes to continuously — every sync, every queue change, every placed track. On a spinning disk
those small random writes contend with the large sequential reads Plex is doing to stream, and the
symptom is Plex stuttering while Plexify works. Point DATA_DIR at an SSD or NVMe volume and the
contention disappears; your music can stay on the big slow disks, because that side is sequential
and cached. On a NAS with an NVMe cache slot, that slot is the right home for it.
The engine is the part that does the work: it syncs your Spotify likes on a timer, decides what is missing, acquires it, files it, and tells Plex. Those are scheduled jobs, so they only happen while the engine is up. On a NAS or server that is always on, that is continuous and invisible. On a laptop it is not — a laptop that sleeps is an engine that stops, and the symptom is silent: nothing errors, music just quietly stops appearing.
Plexify ships a native macOS app. It is a front end, not a second copy of Plexify — point it at your engine and it starts no processes, mounts no shares, and touches no files. Close it and the engine keeps syncing and downloading without you.
bash macapp/build.sh
PLEXIFY_ENGINE_URL=http://your-nas:8787 open Plexify.appThat is the whole setup. The app shows which engine it is attached to in Settings → Engine, and
says so plainly if it cannot reach it rather than leaving yesterday's numbers on screen. To make it
permanent, set PLEXIFY_ENGINE_URL in your login environment — see
docs/MACOS.md.
The web page and the Mac app are two windows into the same Plexify — same database, same settings, every feature identical. Use either, or both.
If you have no always-on machine, the Mac app can host the engine itself: leave PLEXIFY_ENGINE_URL
unset and it launches one, mounts your library, and keeps them alive while it runs. This works, but
know the trade-off — in this mode the app starts the engine with PLEXIFY_START_SCHEDULER=0, so
the background jobs do not run on a timer; syncing and acquisition happen when you ask for
them. It is a fine way to try Plexify out, and a poor way to leave it running.
The wizard covers everything most people need. For the full list of environment variables and config keys (URLs, tokens, paths, tuning), see docs/CONFIGURATION.md. All credentials are stored in a local SQLite database (data/plexify.db) and never leave your machine — it is gitignored and must never be committed.
Plexify is a tool for managing your own music library. The acquisition sources it can connect to may let you download copyrighted material; doing so without the right to that material may be illegal where you live and may violate the terms of the services involved.
- On first run you must accept an agreement confirming you'll use Plexify legally and that you own or have the rights to what you download. Downloading is blocked until you do, and the block is enforced in the engine (
nas_downloader), not just the UI. - The maintainers do not host, distribute, or endorse the acquisition of copyrighted material, and provide no warranty. You are solely responsible for how you use this software and for complying with applicable law and each connected service's terms.
- Container mount paths. For historical reasons the engine references some absolute paths internally; the Docker image symlinks them onto clean
/musicand/downloadsmounts, so the compose file stays tidy. Fully genericizing these paths to environment variables is the top open task — good first contribution. - Native macOS app is a developer build (it launches the engine by path). Packaging a self-contained
.appis planned.
Issues and PRs welcome. Please don't include any real credentials, tokens, or a populated data/ directory in a PR — see .gitignore.
MIT.



