Noureddine RAMDI / Metube: a self-hosted yt-dlp web UI with flexible multi-level download configuration

Created Sat, 23 May 2026 20:41:14 +0000 Modified Sat, 23 May 2026 20:41:27 +0000

alexta69/metube

Metube wraps the powerful yt-dlp downloader in a self-hosted web UI, making video and audio downloads from YouTube and many other sites more accessible. It solves the problem of managing complex yt-dlp commands by exposing a three-tiered configuration model for defining download options, enabling users to subscribe to channels or playlists and queue downloads with concurrency control — all from the browser.

What metube does and how it is built

At its core, Metube is a web-based interface to yt-dlp, the widely used Python tool for downloading media from over 1000 sites. Instead of using yt-dlp from the command line, Metube offers a browser UI built in Angular that interacts with a Python backend. The backend manages download queues, subscriptions to channels or playlists, and persistent state storage.

The architecture breaks down into three main parts:

  • The Python backend, which wraps yt-dlp and handles download orchestration, queue management, subscription scanning, and persistent storage of download states.
  • The Angular frontend, providing an interactive UI for users to initiate downloads, manage queues, and configure options.
  • Containerization using Docker to package the entire stack for easy deployment and environment isolation.

Metube supports downloading individual videos, entire playlists, and channels. It features automatic periodic scanning of subscribed channels or playlists for new uploads, triggering downloads automatically. The queue system handles concurrency limits, allowing multiple downloads to run in parallel but controlling resource usage.

Configuration is extensively exposed through environment variables, influencing everything from download behavior, storage paths, yt-dlp options, to web server settings. This makes it flexible for different deployment environments and user needs.

The multi-level yt-dlp options system and configuration tradeoffs

What stands out with Metube is its three-tiered approach to yt-dlp options configuration:

  1. Global options: These are default settings applied to all downloads, defining core behaviors like output directory, format selection, or retry policies.
  2. Named presets: Users can define reusable sets of yt-dlp options grouped under preset names. This allows non-technical users to select a preset from the UI without dealing with raw options.
  3. Per-download overrides: For advanced users, individual downloads can override preset or global options, fine-tuning behavior on a case-by-case basis.

This design balances power and usability. Yt-dlp’s CLI is notoriously complex with many flags and parameters. By encapsulating options into named presets, Metube provides a layer of abstraction that keeps the UI manageable while still exposing the full power of yt-dlp.

Under the hood, this means the backend must merge options at these three levels, resolving conflicts and ensuring the correct command line is passed to yt-dlp. This merging logic adds complexity but significantly improves user experience.

The persistent state management for queues and subscriptions is also a noteworthy design choice. It allows Metube to resume downloads and subscription checks across restarts, which is essential for a reliable self-hosted service.

The tradeoff here is complexity in configuration and state management. Users must understand environment variables and presets to harness full power, which can be a learning curve. Also, the backend is tightly coupled to yt-dlp’s evolving CLI options, meaning maintenance is needed to keep compatibility.

Quick start

To get Metube running quickly, the project provides Docker images and a simple docker-compose example. This containerized approach isolates dependencies and simplifies deployment.

Run Metube standalone with Docker:

docker run -d -p 8081:8081 -v /path/to/downloads:/downloads ghcr.io/alexta69/metube

Or use docker-compose with this snippet:

services:
  metube:
    image: ghcr.io/alexta69/metube
    container_name: metube
    restart: unless-stopped
    ports:
      - "8081:8081"
    volumes:
      - /path/to/downloads:/downloads

Replace /path/to/downloads with your actual download directory path. The backend exposes port 8081 by default.

Environment variables allow you to customize runtime behavior, like user/group IDs (PUID, PGID), logging level (LOGLEVEL), and UI theme (DEFAULT_THEME).

The UI is built with Angular and included in the container image, so no separate frontend build step is needed for basic use.

Verdict

Metube is a practical project for those wanting a self-hosted, browser-based interface over yt-dlp’s powerful but complex CLI. It suits enthusiasts who value fine-grained control over downloads, want playlist/channel subscription automation, and prefer managing downloads through a web UI.

The three-level options configuration is its strongest feature, elegantly balancing usability for non-experts with the flexibility demanded by power users. However, this flexibility comes at the cost of some configuration complexity and a need for familiarity with environment variables and yt-dlp options.

Being Python and Angular-based, it requires moderate familiarity with Docker and containerized apps for deployment. The Docker image and docker-compose support streamline this.

Limitations include dependency on yt-dlp’s command line interface and its maintenance, plus the inherent complexity of video downloading workflows. It’s not a turn-key consumer app but a tool for technically inclined users wanting a robust, customizable downloader.

Overall, Metube fills a niche in the self-hosted media downloader space with a clean architecture and thoughtful UX design around yt-dlp’s capabilities.


→ GitHub Repo: alexta69/metube ⭐ 13,592 · Python