A Node.js / TypeScript wrapper for yt-dlp.
This package runs a platform-specific yt-dlp binary and uses ffmpeg-static by default.
- Fluent builder API
- Download video as file, buffer, or stream
- Extract audio as file, buffer, or stream
- Fetch thumbnail URL
- Built-in yt-dlp binary (auto-installed)
- Built-in FFmpeg (
ffmpeg-static) - Fully typed API
- Debug mode support
npm install @choewy/yt-dlppnpm add @choewy/yt-dlpThis package requires install scripts.
pnpm approve-buildsApprove:
@choewy/yt-dlpffmpeg-static
import { YtDlp } from '@choewy/yt-dlp';
const result = await new YtDlp({
url: 'https://www.youtube.com/watch?v=VIDEO_ID',
})
.mergeFormat('mp4')
.video()
.download();
console.log(result.path);import { YtDlp } from '@choewy/yt-dlp';
const result = await new YtDlp({
url: 'https://vimeo.com/VIDEO_ID',
})
.mergeFormat('mp4')
.video()
.download();
console.log(result.path);const result = await new YtDlp({ url }).mergeFormat('mp4').output('./video.mp4').video().download();const { buffer } = await new YtDlp({ url }).mergeFormat('mp4').video().buffer();import { createWriteStream } from 'fs';
const { stream } = await new YtDlp({ url }).mergeFormat('mp4').video().stream();
stream.pipe(createWriteStream('./video.mp4'));const result = await new YtDlp({ url }).audioFormat('mp3').output('./audio.%(ext)s').audio().download();const thumbnail = await new YtDlp({ url }).thumbnail().url();new YtDlp({ url }).ffmpeg('/usr/local/bin/ffmpeg').video().download();new YtDlp({
url: string,
});All methods are chainable.
ytDlp
.url(url)
.format(format)
.output(path)
.mergeFormat('mp4')
.audioOnly()
.audioFormat('mp3')
.ffmpeg(path)
.quiet()
.noWarnings()
.noProgress()
.retries(3)
.fragmentRetries(3)
.concurrentFragments(4)
.debug(true);| Option | Type | Default | Description |
|---|---|---|---|
url |
string |
required | Target media URL |
ffmpeg |
string |
ffmpeg-static |
Path to ffmpeg binary |
format |
string |
mp4 optimized | yt-dlp format selector |
output |
string |
- | Output path or template (-o) |
playlist |
boolean |
false |
Download playlist instead of single video |
mergeFormat |
'mp4' | 'mkv' | 'webm' |
mp4 |
Merge container format |
audioOnly |
boolean |
false |
Extract audio only (-x) |
audioFormat |
'mp3' | 'm4a' | 'wav' |
- | Audio format |
overwrite |
boolean |
true |
Overwrite existing files |
quiet |
boolean |
true |
Suppress output logs |
noWarnings |
boolean |
true |
Suppress warnings |
noProgress |
boolean |
true |
Disable progress output |
restrictFilenames |
boolean |
false |
Use ASCII filenames only |
paths |
string |
- | Base output directory |
retries |
number |
3 |
Retry count |
fragmentRetries |
number |
3 |
Fragment retry count |
concurrentFragments |
number |
4 |
Parallel fragment downloads |
embedThumbnail |
boolean |
false |
Embed thumbnail into media |
convertThumbnail |
'jpg' | 'png' | 'webp' |
- | Convert thumbnail format |
printJson |
boolean |
false |
Output metadata as JSON |
debug |
boolean |
false |
Print yt-dlp stdout/stderr |
ytDlp.video();{
origin: string;
title: string;
path: string;
}{
origin: string;
title: string;
buffer: Buffer;
}{
origin: string;
title: string;
stream: Readable;
}ytDlp.audio();audio() extracts audio only and supports the same download(), buffer(), and stream() methods as the video API.
Configure the output format before calling audio():
new YtDlp({ url }).audioFormat('mp3').output('./audio.%(ext)s').audio().download();{
origin: string;
title: string;
path: string;
}{
origin: string;
title: string;
buffer: Buffer;
}{
origin: string;
title: string;
stream: Readable;
}ytDlp.thumbnail().url();Returns:
Promise<string | null>;urlis requiredoutputis required for.download()audio()enablesaudioOnly, somergeFormatis ignored for audio extraction- FFmpeg must exist
YtDlp
├─ YtDlpConfig
├─ YtDlpArgsBuilder
├─ YtDlpRunner
├─ YtDlpAudio
├─ YtDlpVideo
└─ YtDlpThumbnail
new YtDlp({ url }).debug(true).video().download();pnpm install
pnpm approve-builds
pnpm build
pnpm testMIT License
Recommended for stable MP4 downloads:
new YtDlp({ url }).mergeFormat('mp4').video().download();