mrkeyoor.com_
Wed 30 Sept 20:35 UTC
Dev Toolsevaluationupdated 27 Aug 2026

yt-dlp review

yt-dlp is a command-line program and Python library for downloading audio, video, subtitles, thumbnails, and metadata from thousands of sites. It handles site-specific extraction, format choice, playlists, authentication, and post-processing that a plain media URL downloader does not.

+955stars / 7d
Verdict

Our yt-dlp run installed 36 packages in 27 seconds and built in 8 seconds, but pytest stopped after 200 failures, many tied to live sites that had changed or rejected requests. It remains the first tool to try for lawful, scriptable media downloads because its extractor coverage and format controls are hard to match. Use the recommended nightly channel, pin a known-good build for automation, and make partial site failure an expected operating condition.

We ran it

Lab card: what happened when we ran yt-dlpScreenshot of yt-dlp (discord.gg/H5MNcFW63r)
Install✓ · 27s36 packages · 37 MB
Build✓ · 8s
Tests✗ · 735s323 passed · 200 failed · 50 skipped of 523 (pytest)
Known vulns0(pip-audit)
Repo1234 files~249,102 lines of source · 12.3 MB · 13 CI workflows · tests dir

Answers from our run

Does yt-dlp build from source?

Dependencies installed in 27 seconds (36 packages), and the build succeeded in 8 seconds. We cloned commit 81ecd58 into a clean Debian container with 3 CPUs and no project-specific setup.

Do yt-dlp's tests pass?

Not all of them: 323 of 523 passed and 200 failed when we ran the project's own test command (pytest). Some failures need services or credentials a bare container does not have.

Does yt-dlp have known vulnerabilities in its dependencies?

pip-audit found none in the dependency tree at the time of our run.

Who should not use yt-dlp?

Users who need a once-installed binary that keeps working against changing sites: the README recommends nightly builds because stable releases can become stale as sites change.

What are the alternatives to yt-dlp?

youtube-dl, Streamlink, gallery-dl. Our yt-dlp run installed 36 packages in 27 seconds and built in 8 seconds, but pytest stopped after 200 failures, many tied to live sites that had changed or rejected requests.

Setup4/5Small core install; full support needs FFmpeg and JavaScript
Docs5/5Exact options, formats, templates, plugins, and update guidance
Community5/5187,196 stars and extractor fixes active in August 2026
Maturity4/5Deep feature set, but third-party site changes cause constant churn

Discussed on

  1. hnYt-dlp: Upcoming new requirements for YouTube downloads1,244 points
  2. hnYt-dlp: External JavaScript runtime now required for full YouTube support1,106 points
  3. hnYt-dlp – A YouTube-dl fork with additional features and fixes822 points
  4. hnBun support is now limited and deprecated594 points
  5. hnYouTube DRM added on ALL videos with TV (TVHTML5) clients410 points

Who it’s for

People archiving media they are entitled to download from supported sites.
Developers who need a scriptable downloader with structured metadata and filename templates.
Researchers and media teams willing to update frequently as site extractors break and recover.
Python applications that need to call the downloader API and handle site-specific failures explicitly.

Who it’s NOT for

Users who need a once-installed binary that keeps working against changing sites: the README recommends nightly builds because stable releases can become stale as sites change.
Minimal systems that cannot install FFmpeg and a JavaScript runtime: the README says FFmpeg is needed for merging and post-processing, while yt-dlp-ejs plus a JS engine is required for full YouTube support.
Workflows that require every advertised site to pass unattended: our run stopped after 200 live download-test failures across several extractors.
Anyone expecting authentication to guarantee every format: issue 17542 reports an age-restricted YouTube video limited to 360p even with browser cookies and the current stable release.

Setup reality

Our sandbox installed yt-dlp in 27 seconds, adding 36 packages and using 37 MB on disk. The build succeeded in 8 seconds. Tests exited with code 1 after 735 seconds: 323 passed, 200 failed, and 50 skipped out of 523 before pytest stopped at its 200-failure limit.

The Python package can run alone for some downloads, but the README strongly recommends ffmpeg, ffprobe, yt-dlp-ejs, and a supported JavaScript runtime. Cookies, proxies, browser impersonation, or site credentials may be needed for restricted content.

The failure tail shows extractor errors for Bibel TV and Bild, HTTP 412 responses from BiliBili, changed playlist counts, and an invalid Bigo test definition. These are concrete failures from our networked run, not a single local dependency error. Pip-audit found 0 known vulnerabilities.

yt-dlp turns unstable media pages into scriptable downloads

yt-dlp accepts a page URL, identifies the site, extracts available media, chooses formats, and writes files using a configurable naming template. It can also save subtitles, thumbnails, comments, chapters, and structured metadata. For automation, that is much more useful than copying a media URL from browser tools because the command can express playlist filtering, archive history, retries, output layout, and post-processing in one reproducible invocation.

Its scope is huge. Our commit 81ecd58 checkout contained 1,234 files, about 249,102 lines of source, and occupied 12.3 MB. Much of the maintenance burden comes from site-specific extractors whose inputs are controlled by other companies. A website can change a JSON shape, require a different client identity, block a request, or move a playlist endpoint without coordinating with yt-dlp. Extractor health is therefore a moving target.

Full YouTube support now needs JavaScript beside Python

Python 3.10 or newer is supported on CPython, while PyPy starts at 3.11. The core package has many optional dependencies, yet the README strongly recommends 4 pieces: ffmpeg, ffprobe, yt-dlp-ejs, and a supported JavaScript runtime. Deno is the recommended runtime, with Node.js, Bun, and QuickJS also listed. The EJS component handles JavaScript challenges required for full YouTube support.

FFmpeg has a separate job. Many sites publish the best video and audio as distinct streams, so yt-dlp downloads both and asks FFmpeg to merge them. Audio extraction, recoding, subtitle embedding, metadata work, and other post-processors also depend on it. Installing the Python package named ffmpeg is not sufficient; the README specifically requires the executable. Container images should pin and verify that binary alongside yt-dlp.

What happened when we ran it

Our sandbox installed 36 Python packages in 27 seconds and used 37 MB on disk. The build completed successfully in 8 seconds. Pip-audit reported 0 known vulnerabilities in the installed packages. We tested commit 81ecd58 in a fresh Python 3.12 Debian container with 3 CPUs, 8 GB of RAM, no secrets, and network access available to the test command.

Pytest exited with code 1 after 735 seconds. It reported 323 passed, 200 failed, and 50 skipped out of 523, plus 39 passing subtests. The suite stopped after reaching its 200-failure threshold, with 726.40 seconds recorded in the final summary. This was not a marginal failure or a timeout after an otherwise clean suite.

The tail shows several kinds of failure. Bibel TV extractors could not find expected page data. Bild responses failed JSON parsing. BiliBili requests received HTTP 412, and one BiliBili playlist returned 1 entry where the test expected 26. A Bigo case said its own test definition lacked the required output-extension field. These results mix remote-site behavior with a test-definition problem; the log does not provide one cause for all 200 failures.

Nightly is the practical channel because stable can go stale

The project offers stable, nightly, and master binary channels. Stable is published roughly monthly, but the README says external site changes can make it stale and recommends nightly for regular users. Nightly publishes on days with source changes, while master publishes after every push and may contain more regressions. Users reporting a stable-channel bug are asked to reproduce it on nightly or master first.

That policy fits the August 19, 2026 release. Its changelog includes extractor fixes or reworks for Apple, Bandcamp, BFMTV, Instagram, Showroom, TikTok, Twitter, Vimeo, Whyp, and YouTube. GitHub recorded the last push on August 26, followed by more site fixes that day. For personal use, staying on nightly is reasonable. For a production job, test nightly, then pin the exact artifact until the next controlled update.

Authentication can expose formats without guaranteeing them

The CLI can read cookies from major browsers and supports username, password, two-factor codes, .netrc, client certificates, proxies, and browser impersonation through curl_cffi. These options help when a site expects a logged-in or browser-like request. They also move sensitive session data into the downloader process. Run it under an account with the minimum access needed, restrict configuration permissions, and keep verbose logs away from shared storage.

Even complete credentials may not unlock every format. Open issue 17542 shows stable 2026.08.19 using 3,309 Chrome cookies, FFmpeg 8.1, Deno 2.6.10, and yt-dlp-ejs 0.8.0, yet an age-restricted YouTube item exposed only format 18 at 360p. The debug log says higher formats needed a PO token that was not supplied. Authentication, JavaScript challenge solving, and format authorization are separate gates.

Format selection is powerful enough to surprise old scripts

Output templates can use metadata fields for directories and filenames, while format expressions filter and sort video, audio, codecs, size, language, and quality. SponsorBlock integration can mark or remove selected segments. Plugins can add extractors and post-processors, and Python applications can embed YoutubeDL rather than launching a subprocess. This breadth rewards explicit configuration because defaults can evolve.

The README already warns that a future default format may change when multiple formats are streamed to standard output through FFmpeg. Licensing also varies by distribution: the repository and PyPI packages use the Unlicense, while PyInstaller executables contain GPLv3+ code and other bundled licenses. GitHub showed 187,196 stars and 2,598 combined issues and pull requests on August 27, 2026. That large, active queue matches a tool maintained against thousands of moving targets.

Alternatives

ProjectWhat it isPick it when
youtube-dlThe older downloader from which yt-dlp ultimately forked.pick this instead when compatibility with an existing youtube-dl workflow matters more than yt-dlp's faster extractor updates and extra options.
StreamlinkA CLI focused on extracting live streams and sending them to a media player.pick this instead when watching a live stream is the goal and archival metadata or post-processing is secondary.
gallery-dlA downloader aimed at image galleries and collections rather than video-first sites.pick this instead when the targets are mainly image galleries and their metadata.

What people are saying

  1. [github-trending] yt-dlp/yt-dlp

Sources

  1. yt-dlp README
  2. yt-dlp repository facts
  3. yt-dlp 2026.08.19 release
  4. Age-restricted YouTube format issue 17542
  5. Ubuntu PPA update issue 17547

More dev tools reviews

gander · lipgloss · roundhouse · GhostTrack · Codex-Dream-Skin · TokenTracker · the whole board →