A YouTube downloader that behaves like an installed Windows app.
One setup.bat, an IDM-style button on the video player, and downloads that run locally on your PC.
MIT licensed · Windows 10/11 · Chrome, Edge, Brave
- Button on the player. A small download icon sits at the top-right of the YouTube player. Click it and the available qualities drop down — clicking one starts the download immediately.
- Instant quality list. Qualities come from the player already running in the page, so the menu opens in milliseconds instead of waiting on a network lookup.
- As fast as your line allows. Every stream is pulled through
aria2cwith 16 connections, and video and audio are fetched at the same time. On a fast connection a 1080p video is usually done before the page finishes buffering it. - One progress bar for the whole job. Video and audio download in parallel, then merge. You see a single bar, then
Combining video… a few seconds, then done — not one bar per stream. - Pause, resume, cancel.
❚❚freezes the download and keeps the partial file,▶picks it back up,✕stops it. - Nothing is lost when you click away. The download is owned by the extension's background worker, so closing the panel or the popup — or opening a different tab — never interrupts it, and the panel reconnects to the running job when you open it again.
- Finished files listed. The last downloads appear under Already downloaded, each with a button that reveals the file in Explorer.
- Paste any link. The toolbar popup takes any YouTube URL, shows a thumbnail preview, and downloads video (up to 8K when available) or MP3 audio.
- Fully local. No accounts, no servers, no telemetry. The extension talks only to a helper on your own machine.
- One file installs it.
setup.batfetches whatever is missing, skips whatever is already there, and pairs itself with your browser — no copy-pasting IDs, no compiler, no admin rights.
-
Download this project and unzip it anywhere — a portable folder is fine.
-
Run
setup.bat(double-click; no administrator rights needed). It walks through six steps and shows a progress bar for anything it has to fetch:Step What happens 1 · Checking this PC reports what is already installed, so a second run has nothing to do 2 · Local helper app copies the helper and the extension into %LOCALAPPDATA%\YtDownlaoder3 · Downloader tools yt-dlp,aria2c, FFmpeg, FFprobe, Deno — only the missing ones are downloaded, andyt-dlpis updated on every run4 · Register with Windows Installed apps entry and a Start Menu shortcut 5 · Pair with your browser writes the native-messaging manifest for the extension folder 6 · Final check prints the version of every tool -
Load the extension once, using the folder setup prints at the end:
Open
chrome://extensions→ turn on Developer mode → Load unpacked → pick%LOCALAPPDATA%\YtDownlaoder\extension
That's it — no ID to copy. An unpacked extension's ID is derived from its folder path, so setup computes the same ID Chrome will and pairs the helper with it in advance. Downloads go to Downloads\Yt-Downlaoder unless you change the folder in the popup.
Running setup.bat again is always safe: with everything in place it finishes in a few seconds and reports Already set up. Nothing needed changing on this PC.
After editing anything in this project's
extension/folder, runsetup.batagain (it re-copies the files), then click Reload on Yt-Downlaoder inchrome://extensionsand refresh the YouTube tab.
YouTube page Chrome extension Your PC
┌──────────────────┐ ┌───────────────────┐ ┌──────────────────────┐
│ player button │◄──────►│ background worker │◄──────►│ YtDownloadHost.exe │
│ quality dropdown │ msgs │ owns the job: │ native │ spawns yt-dlp, │
│ progress + files │ │ progress, pause │ msgs │ merges with FFmpeg │
└──────────────────┘ └───────────────────┘ └──────────────────────┘
- Content script (
extension/content.js) draws the in-page button and panel. It never downloads anything itself; it asks the worker and renders whatever state comes back. - Background worker (
extension/background.js) is the single source of truth for the running download. Any window can ask it forliveStateand catch up, which is why the UI survives being closed. It also reads the page's own player throughchrome.scripting.executeScriptto build the quality list with no network call. - Native messaging host (
native-host/YtDownloadHost) is a small self-contained .NET app. Chrome starts it on demand and talks to it over stdin/stdout, so there is no local web server and no open port. It runsyt-dlp, parses its output into one monotonic progress value, and reports the real file name it wrote. - Pause/resume across processes. Chrome starts a fresh host process for every request, so a pause click cannot reach the running download in memory. The host writes a tiny flag file that the downloading process polls, then suspends or resumes the
yt-dlpthreads. The partial.partfile stays on disk, so resuming continues instead of restarting.
| Choice | Effect |
|---|---|
aria2c as the downloader, -x16 -s16 -k1M |
one stream arrives over 16 connections instead of one |
| Quality list read from the loaded player | menu opens instantly instead of a multi-second lookup |
--concurrent-fragments 16, --http-chunk-size 10M |
many fragments download in parallel when a stream is fragmented |
Height selectors (bv*[height<=1080]+ba) |
best stream for that resolution, no format-id lookup |
--extractor-args youtube:skip=hls |
skips a manifest fetch that is never used |
--continue |
a canceled or paused download resumes where it stopped |
| Format results cached per video for 10 minutes | reopening the menu costs nothing |
If aria2c is missing for any reason the helper falls back to yt-dlp's own downloader — everything still works, just slower.
setup.bat installer, repair and uninstaller in one file
extension/ the Chrome extension (setup copies this to %LOCALAPPDATA%)
manifest.json background.js content.js common.js popup.* styles.css
native-host/YtDownloadHost/ C# native messaging host
native-host/publish/ the prebuilt helper that ships with the repo
scripts/make-icons.ps1 regenerates the icon set and app.ico
You don't need to. native-host/publish/YtDownloadHost.exe is committed — a trimmed, self-contained single file, so setup.bat needs neither the .NET SDK nor .NET itself on the target PC.
To rebuild it after changing Program.cs (needs the .NET 8 SDK):
dotnet publish native-host/YtDownloadHost -c Release -o native-host/publishsetup.bat only builds the helper if native-host/publish/YtDownloadHost.exe is absent — and then it offers to install the SDK with winget first. After rebuilding by hand, run setup.bat again to copy the new exe into place.
Use Installed apps → Yt-Downlaoder → Uninstall, or run:
setup.bat /uninstallThat removes the helper folder, the browser registrations, the Start Menu shortcut and the registry entry. Downloaded videos are left alone. Then remove the extension from chrome://extensions.
| Symptom | Fix |
|---|---|
| Setup needed — run setup.bat | The extension is loaded from a folder the helper isn't paired with. Run setup.bat again — it re-pairs whatever folder the extension is actually loaded from. |
| Yt-Downlaoder was updated. Refresh this page. | Normal after reloading the extension — refresh the YouTube tab. |
| No 4K/8K option | That resolution isn't offered for the video. |
| Downloads fail after working for weeks | Run setup.bat again; it updates yt-dlp, which YouTube changes break regularly. |
| Nothing happens on click | Confirm %LOCALAPPDATA%\YtDownlaoder\YtDownloadHost.exe exists, then re-run setup.bat. |
| Downloads feel slow | Check the final list in setup.bat — if aria2c is marked missing, re-run setup so it can fetch it. |
Download only what you own or are allowed to download, and respect copyright, YouTube's terms and your local law. This project is not affiliated with, endorsed by, or connected to Google or YouTube.
MIT © 2026 Ahmad Farooq
Bundled tools keep their own licenses: yt-dlp (Unlicense), aria2 (GPLv2+), FFmpeg (LGPL/GPL), Deno (MIT). They are downloaded by setup.bat from their official release pages, not redistributed here.