Self-hosted YouTube Music downloader. Paste a link, get a tagged, organized library.
Playlist sync. Artist/year sorting. Duplicate detection. Media server ready.
Downloading music is easy. Organizing it is the hard part.
yubal takes a YouTube Music URL and produces a clean, tagged music library:
data/
├── Pink Floyd/
│ └── 1973 - The Dark Side of the Moon/
│ ├── 01 - Speak to Me.opus
│ ├── 01 - Speak to Me.lrc
│ ├── 02 - Breathe.opus
│ ├── 02 - Breathe.lrc
│ └── cover.jpg
│
├── Radiohead/
│ └── 1997 - OK Computer/
│ ├── 01 - Airbag.opus
│ ├── 01 - Airbag.lrc
│ ├── 02 - Paranoid Android.opus
│ ├── 02 - Paranoid Android.lrc
│ └── cover.jpg
│
└── _Playlists/
├── My Favorites [n2g-XhDv].m3u
└── My Favorites [n2g-XhDv].jpg
When downloading a playlist, each track goes to its album folder—the M3U file just references them:
#EXTM3U
#EXTINF:239,Pink Floyd - Breathe
../Pink Floyd/1973 - The Dark Side of the Moon/02 - Breathe.opus
#EXTINF:386,Radiohead - Paranoid Android
../Radiohead/1997 - OK Computer/02 - Paranoid Android.opus- Web UI — Real-time progress, job queue, responsive design
- Albums, playlists & tracks — Paste any YouTube Music link, get organized files
- Scheduled sync — Subscribe to playlists; new tracks download automatically
- Smart deduplication — Same track across 10 playlists? Stored once, referenced everywhere
- Reliable downloads — Automatic retry on failures, graceful cancellation
- Automatic lyrics — Synced
.lrcfiles downloaded alongside tracks when available - ReplayGain tagging — Track and album ReplayGain/R128 tags for consistent playback volume
- Format options — Native
opus(best quality), mp3, or m4a (direct download when available, transcoded otherwise) - Media server ready — Tested with Navidrome, Jellyfin, and Gonic
- CLI — Download and inspect metadata from the terminal
Download tracks and subscribe to playlists directly from YouTube and YouTube Music without leaving the page.
More info in the extension's README.md.
# compose.yaml
services:
yubal:
image: ghcr.io/guillevc/yubal:latest
container_name: yubal
user: 1000:1000
ports:
- 8000:8000
environment:
YUBAL_SCHEDULER_CRON: "0 0 * * *"
YUBAL_DOWNLOAD_UGC: false
YUBAL_TZ: UTC
volumes:
- ./data:/app/data
- ./config:/app/config
restart: unless-stoppedTip
Volume permissions: The container runs as UID:GID 1000:1000 by default. If your host user has a different UID, either:
- Change
user:to match your UID:GID (runidto check), or - Set ownership on the volume directories:
chown 1000:1000 -R data config
docker compose up -d
# Open http://localhost:8000Unraid? Use the community Docker template by @SerpentDrago (unraid forum thread).
| Variable | Description | Default (Docker) |
|---|---|---|
YUBAL_AUDIO_FORMAT |
opus, mp3, or m4a |
opus |
YUBAL_AUDIO_QUALITY |
Transcode quality (0=best, 10=worst) | 0 |
YUBAL_SCHEDULER_ENABLED |
Enable automatic scheduled sync | true |
YUBAL_SCHEDULER_CRON |
Cron schedule for auto-sync | 0 0 * * * |
YUBAL_FETCH_LYRICS |
Fetch lyrics from lrclib.net | true |
YUBAL_DOWNLOAD_UGC |
Download user-generated content to _Unofficial/ |
false |
YUBAL_REPLAYGAIN |
Apply ReplayGain tags to downloads | true |
YUBAL_JOB_TIMEOUT_SECONDS |
Job execution timeout in seconds | 1800 |
YUBAL_TZ |
Timezone (IANA format) | UTC |
All options
| Variable | Description | Default (Docker) |
|---|---|---|
YUBAL_HOST |
Server bind address | 127.0.0.1 |
YUBAL_PORT |
Server port | 8000 |
YUBAL_DATA |
Music library output | /app/data |
YUBAL_CONFIG |
Config directory | /app/config |
YUBAL_LOG_LEVEL |
DEBUG, INFO, WARNING, ERROR |
INFO |
YUBAL_ASCII_FILENAMES |
Transliterate unicode to ASCII | false |
YUBAL_CORS_ORIGINS |
Allowed CORS origins | ["*"] |
YUBAL_TEMP |
Temp directory | System temp |
Tested with Navidrome, Jellyfin, and Gonic. Artists link correctly, even on tracks with multiple artists.
| Server | Artist linking | Playlists |
|---|---|---|
| Navidrome | ✅ Works out of the box | ✅ |
| Jellyfin | ⚙️ Enable "Use non-standard artists tags" in library settings | ✅ |
| Gonic | ⚙️ Set GONIC_MULTI_VALUE_ARTIST=multi |
❌ |
✅ Supported · ⚙️ Requires configuration · ❌ Not supported
Detailed setup guides
No configuration required. Optionally, make imported playlists public:
ND_DEFAULTPLAYLISTPUBLICVISIBILITY=trueSee Navidrome docs.
For multi-artist support:
- Dashboard → Libraries → Music Library → Manage Library
- Check Use non-standard artists tags
- Save and rescan
For artist linking:
GONIC_MULTI_VALUE_ARTIST=multi
GONIC_MULTI_VALUE_ALBUM_ARTIST=multiM3U playlists are not supported (pending PR).
Need age-restricted content, private playlists, or Premium quality? Add your cookies:
- Export
https://www.youtube.com/cookies with a browser extension (yt-dlp guide) - Place at
config/ytdlp/cookies.txtor upload via the web UI
Caution
Cookie usage may trigger stricter rate limiting and could put your account at risk. See #3 and yt-dlp wiki.
- Playlist support with M3U generation (v0.2.0)
- Single track downloads (v0.3.0)
- Automatic lyrics (.lrc) (v0.3.0)
- Auto-sync playlists (v0.4.0)
- UGC tracks (user-generated content, remixes, unofficial tracks) (v0.5.0)
- Browser extension (v0.7.0, ext-v0.1.0)
- Flat folder mode
- Post-download webhooks
- New music automatic discovery
If yubal is useful to you, consider supporting its development:
A ⭐ also helps others discover yubal!
Built with yt-dlp and ytmusicapi.
Thanks to everyone who's starred, shared, reported bugs, suggested features, or supported the project 💝
For personal archiving only. Comply with YouTube's Terms of Service and applicable copyright laws.