Self-hosted, any-to-any music playlist and library migration, local-first generation, and portable export.
Website · Overview · Features · Supported providers · Quick start · Documentation · Development
Open Playlist Engine moves music-library metadata between supported providers without moving or streaming audio. It can:
- migrate playlists, liked tracks, saved albums, and followed or favorite artists;
- import local playlist files, public playlist URLs, and pasted track lists;
- generate editable playlists through an administrator-configured model;
- view each logical playlist across connected providers;
- export, share, snapshot, synchronize, and organize playlists.
It is the first reference implementation of the
open-playlist universal
Playlist/Track specification. Providers are plugin spokes around that universal
format, so each new provider can work with every existing provider as both a source
and a target.
Status: Early MVP. The UI advertises only the capabilities implemented by each provider and keeps unsupported operations disabled.
provider, file, URL, or text ─▶ [ Open Playlist hub ] ─▶ target provider
│
└───────────────▶ local export
Migrations follow a durable import → match → review → write pipeline. Matching
uses provider identifiers and an evidence graph; low-confidence results require
human review before anything is written. See
docs/DESIGN.md for the architecture and trust boundaries.
| Capability | What it provides | Guide |
|---|---|---|
| Playlist migration | Track selection, matching, review, duplicate protection, and live progress | Design |
| Unified playlists | Provider-neutral playlist and song coverage with keep-everywhere sync | Unified playlists |
| Local file imports | TXT, CSV, M3U/M3U8, PLS, WPL, XSPF, XML, and JSON sources | Local imports |
| URL and text imports | Bounded public playlist URLs and pasted track lists | Import sources |
| Portable exports | CSV, TXT, M3U8, XSPF, JSON, and multi-playlist ZIP downloads | Exports |
| Playlist generator | Private editable drafts resolved to real provider tracks before writing | Generator |
| Library snapshots | Versioned, metadata-only local backups, verification, diff, and restore | Snapshots |
| Scheduled sync | Persistent add-only and capability-gated mirror rules | Synchronization |
| Playlist Organizer | Capability-gated library cleanup with preflight and durable retries | Organizer |
| History and reports | Reopenable migrations, statistics, and streamed CSV/JSON reports | Migration history |
| Playlist sharing | Opt-in immutable snapshots with isolated recipient credentials | Sharing |
| Provider | Playlists / liked tracks | Saved albums | Followed/favorite artists |
|---|---|---|---|
| Spotify | Read/write | Read/write | Read/write as follows |
| Tidal | Read/write | Read/write | Read/write as favorites |
| YouTube Music | Read/write | Unsupported | Unsupported |
| Apple Music | Read/write | Unsupported | Unsupported |
Exact source, target, authentication, and Organizer capabilities are provider-driven.
For app registration, callback URLs, scopes, and connection behavior, see
docs/CONNECTING_PROVIDERS.md.
Docker Compose starts Postgres, Valkey, the API, worker, and frontend:
Existing Docker deployments using PostgreSQL 17 must complete the PostgreSQL 18 data migration before starting this version.
cp .env.example .env
# Edit .env: replace OPE_SECRET_KEY and add credentials for the providers you use.
docker compose build --no-cache
docker compose up- App: http://localhost:8080
- API documentation: http://localhost:8000/docs
- API health: http://localhost:8000/health
All backend settings use the OPE_ prefix. Start with
.env.example, then read the
configuration guide and
provider setup guide. The optional local Ollama
profile is documented in the
playlist generator guide.
cd backend
python -m venv .venv
. .venv/bin/activate
python -m pip install -e ".[dev]"
python -m alembic upgrade head
uvicorn app.main:app --reload --no-access-logRun the worker in another shell from backend/:
arq app.jobs.worker.WorkerSettingscd frontend
npm ci
npm run devThe development frontend runs at http://localhost:5173 and proxies /api to the
backend. Required checks and exact local commands are listed in
docs/CI.md.
| Path | Contents |
|---|---|
backend/ |
FastAPI API, provider adapters, matching, jobs, and database code |
frontend/ |
React SPA and generated OpenAPI client |
openapi/ |
Vendored Open Playlist specification and generated engine contract; the standard's API reference remains on the Open Playlist website |
docs/ |
Architecture, setup, feature guides, and ADRs |
The frontend and backend are hard-separated: the frontend communicates only through the backend's generated OpenAPI contract.
Browse the rendered documentation website
or the categorized docs/ source index. Start with:
- Configuration
- Connecting providers
- Product purpose and design principles
- Architecture and provider contract
- Continuous integration
Implement ProviderAdapter in backend/app/providers/<name>/adapter.py, declare a
CapabilityDescriptor, register it, and pass the conformance suite in
backend/tests/conformance/. See the
provider plugin contract and
backend/README.md.