A simple Node.js wrapper around yt-dlp using youtube-dl-exec.
This script lets you download YouTube videos with:
- Interactive resolution menu (1080p, 720p, 480p, or audio-only).
- MP4 output by default, with merging handled by
ffmpeg
. - Built-in yt-dlp progress bar in the terminal.
- Subtitles (optional).
- Playlist support.
- Batch/concurrent downloading.
- Resume support.
- Node.js v18+ (works best with v20+).
- ffmpeg (for merging video/audio and audio-only mode).
On macOS:
brew install ffmpeg
On Linux (Debian/Ubuntu):
sudo apt install ffmpeg
Clone or copy the script into your project folder, then install dependencies:
npm init -y
npm install youtube-dl-exec
Make it executable (optional):
chmod +x download.mjs
node download.mjs "https://youtu.be/VIDEO_ID"
You’ll be prompted to choose a quality:
Choose output quality (applies to all URLs this run):
1) MP4 up to 1080p (best <=1080)
2) MP4 up to 720p
3) MP4 up to 480p
4) Audio-only (M4A)
Enter 1/2/3/4 [default 1]:
If you want to skip the interactive menu:
- Force format manually
node download.mjs --format "bestvideo[ext=mp4][height<=720]+bestaudio[ext=m4a]/best[ext=mp4]" URL
- Audio only
node download.mjs --audio URL
- Disable prompt entirely
node download.mjs --noPrompt URL
- Multiple URLs
node download.mjs URL1 URL2 URL3
- Read from a file
node download.mjs --fromFile urls.txt
- Custom output folder
node download.mjs --outDir ./my_downloads URL
- Subtitles
node download.mjs --subs --lang en URL
- Cookies (for age-gated/private videos)
node download.mjs --cookies ./cookies.txt URL
- Proxy
node download.mjs --proxy "socks5://127.0.0.1:1080" URL
- Download a playlist but stop at 720p:
node download.mjs --format "bestvideo[ext=mp4][height<=720]+bestaudio[ext=m4a]/best[ext=mp4]" "https://www.youtube.com/playlist?list=XXXX"
- Download audio-only as MP3:
node download.mjs --audio --audioFormat mp3 URL
- Batch file with subtitles:
node download.mjs --fromFile urls.txt --subs --lang en
- Concurrency: Default is 2 downloads at once.
node download.mjs --concurrent 4 --fromFile urls.txt
- Retries: Default is 2.
node download.mjs --retries 5 URL
- Rate limiting (useful on unstable connections):
node download.mjs --rateLimit 2M URL
- The progress bar comes from yt-dlp itself (via
stdio: "inherit"
). - If you see
WARNING: You have requested merging of multiple formats but ffmpeg is not installed
, installffmpeg
as described above. - If downloads fail with
403 Forbidden
errors, try:
node download.mjs --extractorArgs "youtube:player_client=android" --geo AU URL
MIT — free to use, modify, and share.