Yubal
Self-hosted YouTube Music downloader. Tags, organizes, and keeps playlists in sync.
Install / Use
/learn @guillevc/YubalREADME
yubal
Self-hosted YouTube Music downloader. Paste a link, get a tagged, organized library.
Playlist sync. Artist/year sorting. Duplicate detection. Media server ready.
<picture> <img src="docs/demo.gif" alt="yubal demo" width="75%"> </picture> </div> <br/>📖 How It Works
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
✨ Features
- 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
🧩 Browser Extension
Download tracks and subscribe to playlists directly from YouTube and YouTube Music without leaving the page.
<p> <img src="https://raw.githubusercontent.com/guillevc/yubal/refs/heads/master/extension/docs/images/extension-track.png" alt="Track view" width="32%"> <img src="https://raw.githubusercontent.com/guillevc/yubal/refs/heads/master/extension/docs/images/extension-playlist.png" alt="Playlist view" width="32%"> <img src="https://raw.githubusercontent.com/guillevc/yubal/refs/heads/master/extension/docs/images/extension-settings.png" alt="Settings view" width="32%"> </p> <p> <a href="https://addons.mozilla.org/addon/yubal/"><img src="https://img.shields.io/badge/Firefox-get_add--on-FF7139?logo=firefox&logoColor=white&style=for-the-badge" alt="Get the add-on for Firefox"></a> <a href="https://github.com/guillevc/yubal/releases?q=🧩"><img src="https://img.shields.io/badge/Chrome-manual_install-4285F4?logo=googlechrome&logoColor=white&style=for-the-badge" alt="Chrome manual install"></a> </p>More info in the extension's README.md.
🚀 Quick Start
# 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-stopped
[!TIP] Volume permissions: The container runs as UID:GID
1000:1000by 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:8000
Unraid? Use the community Docker template by @SerpentDrago (unraid forum thread).
⚙️ Configuration
| 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 |
| 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 |
🔌 Media Server Integration
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
<details> <summary>Detailed setup guides</summary>Navidrome
No configuration required. Optionally, make imported playlists public:
ND_DEFAULTPLAYLISTPUBLICVISIBILITY=true
See Navidrome docs.
Jellyfin
For multi-artist support:
- Dashboard → Libraries → Music Library → Manage Library
- Check Use non-standard artists tags
- Save and rescan
Gonic
For artist linking:
GONIC_MULTI_VALUE_ARTIST=multi
GONIC_MULTI_VALUE_ALBUM_ARTIST=multi
M3U playlists are not supported (pending PR).
</details>🍪 Cookies (Optional)
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.
🗺️ What's Coming
- [x] Playlist support with M3U generation (v0.2.0)
- [x] Single track downloads (v0.3.0)
- [x] Automatic lyrics (.lrc) (v0.3.0)
- [x] Auto-sync playlists (v0.4.0)
- [x] UGC tracks (user-generated content, remixes, unofficial tracks) (v0.5.0)
- [x] Browser extension (v0.7.0, ext-v0.1.0)
- [ ] Flat folder mode
- [ ] Post-download webhooks
- [ ] New music automatic disco
