⚠️ Notice: Version 3.4.0 is currently in beta. While we've thoroughly tested the new features, please report any issues you encounter on our GitHub Issues page. Your feedback helps make this library better!
ytdlp-nodejs

A powerful Node.js wrapper for yt-dlp that provides a simple, type-safe interface for downloading, streaming, and fetching metadata from videos across thousands of websites.
📚 View Full Documentation
Features
- 🚀 Easy to use - Simple API with TypeScript support
- 📥 Download & Stream - Download videos or stream them directly
- 📊 Progress tracking - Real-time download progress callbacks
- 🎵 Audio extraction - Extract audio in various formats (MP3, FLAC, etc.)
- 📋 Metadata fetching - Get video info, formats, thumbnails, and more
- 🔄 Auto-updates - Built-in yt-dlp binary management
- 💻 CLI included - Interactive and non-interactive command-line interface
- 🌐 Node.js runtime - Uses Node.js as the default JavaScript runtime for yt-dlp
Installation
npm install ytdlp-nodejs
Note: FFmpeg is recommended for full functionality. Install it manually or use the built-in downloadFFmpeg() method.
Quick Start
import { YtDlp } from 'ytdlp-nodejs';
const ytdlp = new YtDlp();
const result = await ytdlp
.download('https://youtube.com/watch?v=dQw4w9WgXcQ')
.filter('mergevideo')
.quality('1080p')
.type('mp4')
.on('progress', (p) => console.log(`${p.percentage_str}`))
.run();
console.log('Downloaded:', result.filePaths);
const info = await ytdlp.getInfoAsync(
'https://youtube.com/watch?v=dQw4w9WgXcQ',
);
console.log(info.title);
import { createWriteStream } from 'fs';
const stream = ytdlp.stream('https://youtube.com/watch?v=dQw4w9WgXcQ');
await stream.pipeAsync(createWriteStream('video.mp4'));
CLI Usage
Interactive Mode
Launch the interactive menu to access all features with guided prompts:
ytdlp
Direct Commands
These commands run without prompts:
ytdlp formats <url>
ytdlp video <url> --quality 1080p
ytdlp ffmpeg
ytdlp update
API Reference
Constructor
const ytdlp = new YtDlp({
binaryPath?: string,
ffmpegPath?: string,
});
Download Methods
download(url, options?)
Returns a fluent builder for downloading with chainable methods.
const result = await ytdlp
.download('https://youtube.com/watch?v=...')
.format({ filter: 'mergevideo', quality: '1080p', type: 'mp4' })
.output('./downloads')
.embedThumbnail()
.on('progress', (p) => console.log(`${p.percentage_str}`))
.run();
console.log('Files:', result.filePaths);
const result = await ytdlp
.download(url, {
format: { filter: 'mergevideo', quality: '1080p', type: 'mp4' },
})
.embedThumbnail()
.on('progress', (p) => console.log(p))
.run();
Builder Methods
| Format | .filter(), .quality(), .type(), .format() |
| Output | .output('./downloads'), .setOutputTemplate('%(title)s.%(ext)s') |
| Audio | .extractAudio(), .audioFormat('mp3'), .audioQuality('0') |
| Embed | .embedThumbnail(), .embedSubs(), .embedMetadata() |
| Subtitles | .writeSubs(), .writeAutoSubs(), .subLangs(['en', 'es']) |
| Thumbnail | .writeThumbnail() |
| Auth | .cookies(str), .cookiesFromBrowser('chrome'), .username(user), .password(pass) |
| Network | .proxy(url), .rateLimit('1M') |
| Playlist | .playlistStart(1), .playlistEnd(10), .playlistItems('1,3,5') |
| Advanced | .options(argsOptions), .addOption(key, value), .addArgs(...args), .skipDownload() |
| Events | .on('start' | 'progress' | 'beforeDownload' | 'stdout' | 'stderr' | 'error' | 'finish', fn) |
| Execute | .run() - returns Promise<DownloadFinishResult> - Also directly awaitable |
downloadAsync(url, options?)
Downloads a video asynchronously with callback-style progress.
const result = await ytdlp.downloadAsync(url, {
format: { filter: 'mergevideo', type: 'mp4', quality: '1080p' },
output: './downloads/%(title)s.%(ext)s',
onProgress: (progress) => console.log(progress),
});
downloadAudio(url, format?, options?)
Downloads audio only.
await ytdlp.downloadAudio(url, 'mp3');
downloadVideo(url, quality?, options?)
Downloads video with specific quality.
await ytdlp.downloadVideo(url, '1080p');
Streaming
stream(url, options?)
Returns a fluent builder for streaming with chainable methods.
import { createWriteStream } from 'fs';
const result = await ytdlp
.stream('https://youtube.com/watch?v=...')
.filter('audioandvideo')
.quality('highest')
.type('mp4')
.on('progress', (p) => console.log(p.percentage_str))
.pipeAsync(createWriteStream('video.mp4'));
console.log(`Bytes: ${result.bytes}`);
ytdlp.stream(url).filter('audioandvideo').pipe(writableStream);
const buffer = await ytdlp.stream(url).filter('audioonly').toBuffer();
Stream Builder Methods
.filter(), .quality(), .type() | Set format options (same as Download) |
.pipe(dest, options?) | Pipe to writable stream, returns Promise |
.pipeAsync(dest, options?) | Alias for .pipe() |
.toBuffer() | Collect stream into Buffer |
.getStream() | Get underlying PassThrough stream |
.on('start' | 'progress' | 'beforeDownload' | 'data' | 'error' | 'end', fn) | Event listeners |
getFileAsync(url, options?)
Returns a File object without saving to disk.
const file = await ytdlp.getFileAsync(url, {
format: { filter: 'audioonly', type: 'mp3' },
onProgress: (p) => console.log(p),
});
console.log(file.name, file.size);
Information Methods
getInfoAsync(url, options?)
Fetches video/playlist metadata.
const info = await ytdlp.getInfoAsync(url);
console.log(info.title, info.duration, info.formats);
getFormatsAsync(url, options?)
Gets available formats using JSON output.
const result = await ytdlp.getFormatsAsync(url);
console.log(`Found ${result.formats.length} formats`);
getDirectUrlsAsync(url, options?)
Returns direct media URLs.
const urls = await ytdlp.getDirectUrlsAsync(url);
getTitleAsync(url)
const title = await ytdlp.getTitleAsync(url);
getThumbnailsAsync(url)
const thumbnails = await ytdlp.getThumbnailsAsync(url);
getVersionAsync()
const version = await ytdlp.getVersionAsync();
Utility Methods
checkInstallationAsync(options?)
const installed = await ytdlp.checkInstallationAsync({ ffmpeg: true });
downloadFFmpeg()
await ytdlp.downloadFFmpeg();
updateYtDlpAsync(options?)
const result = await ytdlp.updateYtDlpAsync();
console.log(`Updated to ${result.version}`);
Format Options
Use structured format options for type-safe configuration:
{ filter: 'videoonly', type: 'mp4', quality: '1080p' }
{ filter: 'audioonly', type: 'mp3', quality: 5 }
{ filter: 'audioandvideo', type: 'mp4', quality: 'highest' }
{ filter: 'mergevideo', type: 'mp4', quality: '1080p' }
Quality Options
videoonly, mergevideo | '2160p', '1440p', '1080p', '720p', '480p', '360p', '240p', '144p', 'highest', 'lowest' |
audioandvideo | 'highest', 'lowest' |
audioonly | 0 to 10 (VBR quality) |
Type Options
videoonly, audioandvideo | 'mp4', 'webm' |
audioonly | 'aac', 'flac', 'mp3', 'm4a', 'opus', 'vorbis', 'wav', 'alac' |
mergevideo | 'mkv', 'mp4', 'ogg', 'webm', 'flv' |
Advanced Options
JavaScript Runtime
Node.js is used as the default JavaScript runtime for yt-dlp extractors:
await ytdlp.execAsync(url, {
jsRuntime: 'node',
});
Raw Arguments
Pass any yt-dlp argument directly:
await ytdlp.downloadAsync(url, {
rawArgs: ['--match-filter', 'duration > 60', '--geo-bypass'],
});
Debug Mode
await ytdlp.execAsync(url, {
debugPrintCommandLine: true,
verbose: true,
});
Troubleshooting
Binary not found
import { helpers } from 'ytdlp-nodejs';
await helpers.downloadYtDlp();
await helpers.downloadFFmpeg();
Or provide custom paths:
const ytdlp = new YtDlp({
binaryPath: '/path/to/yt-dlp',
ffmpegPath: '/path/to/ffmpeg',
});
Built With ytdlp-nodejs
🚀 NextDownloader.com - A video downloader I built using this library. Check it out and let me know what you think! Your feedback is greatly appreciated.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request or open an issue on GitHub.