DEV Community

john jewski
john jewski

Posted on

I Built a Free yt-dlp Web Frontend That Supports 1000+ Sites — Here's How

A few weeks ago I got tired of every video downloader site being a minefield of fake download buttons, popup ads, and malware redirects. So I built dltkk.to — a clean, no-BS web frontend for yt-dlp that anyone can use without installing anything.
Here's what I built, how it works technically, and what I learned shipping it.

What It Does
dltkk.to is a browser-based video downloader powered by yt-dlp on the backend. Paste any video URL, pick a format, hit download. That's it.
Supported formats: MP4, MP3, FLAC, WAV, AAC, MKV, GIF, and thumbnail extraction.
Supported platforms: Anything yt-dlp supports — TikTok, YouTube, Twitter/X, Instagram, Twitch, Vimeo, Facebook, and 1000+ more.
Extra features:

Batch mode — paste up to 10 URLs at once, processes sequentially
GIF conversion — converts video to optimized GIF via ffmpeg
No ads, no watermark, no signup — ever

The Stack
Simple Node.js + Express backend, plain HTML/CSS/JS frontend. No frameworks, no build step. Runs on a single VPS.
javascript// Core download flow — everything routes through /tmp
function streamViaTmp(videoUrl, platform, format, quality, req, res) {
const tmpFile = /tmp/dltkk_${Date.now()}_${rand}.${outputExt};

const ytdlp = spawn('yt-dlp', buildArgs(platform, format, quality, tmpFile, videoUrl));

ytdlp.on('close', code => {
if (code !== 0) return res.status(500).json({ error: parseError(errorOutput) });

// Stream file to client then delete immediately
res.setHeader('Content-Disposition', `attachment; filename="dltkk.${outputExt}"`);
const stream = fs.createReadStream(tmpFile);
stream.pipe(res);
stream.on('finish', () => fs.unlinkSync(tmpFile)); // deleted instantly
Enter fullscreen mode Exit fullscreen mode

});
}

Key Technical Decisions
Why /tmp Instead of a Downloads Folder
My first version saved files to a downloads directory and cleaned them up on a timer. This caused two problems — disk space filling up under load, and files occasionally not getting cleaned up if the server restarted.
The fix was writing everything to /tmp which is RAM-based on Linux. Files never touch the main disk, and cleanup is instant after the stream finishes. Zero disk space issues since.
Why Not Stream Directly via stdout
yt-dlp can pipe directly to stdout with -o - which sounds ideal for streaming. The problem is any format that requires merging separate video and audio streams (most YouTube downloads, many others) needs ffmpeg to write a temp file first. Trying to stream this causes silent failures on certain platforms.
The solution: everything goes through /tmp. It's RAM anyway so there's no meaningful performance difference, and it works reliably across all platforms.
GIF Conversion
javascriptexec(ffmpeg -i "${tmpMp4}" -vf "fps=10,scale=480:-1:flags=lanczos" -loop 0 "${tmpGif}")
Download as MP4 first, convert with ffmpeg, stream the GIF, delete both files. The lanczos scaling algorithm gives the best quality at small file sizes. fps=10 keeps the GIF smooth without bloating the file.
Rate Limiting
3 requests per minute per IP using a simple in-memory Map. Cleans itself up every 5 minutes. Good enough for the current traffic level.
javascriptconst rateLimitMap = new Map();
function rateLimit(ip) {
const now = Date.now();
const timestamps = (rateLimitMap.get(ip) || []).filter(t => now - t < 60000);
timestamps.push(now);
rateLimitMap.set(ip, timestamps);
return timestamps.length > 3;
}

Platform-Specific Quirks
TikTok requires --impersonate chrome-131 or downloads fail. TikTok actively detects and blocks non-browser requests.
Reddit blocks all datacenter IPs at the network level. No amount of header spoofing fixes this — it's an IP range block. Currently showing a friendly error message for Reddit URLs.
Instagram needs a Referer: https://www.instagram.com/ header or it returns 403.
YouTube limits to 10 minutes to prevent abuse and requires specific format selection to get the best quality MP4 merge.

What I'd Do Differently
Proxy layer for Reddit — Reddit blocking is the most common complaint. A residential proxy for Reddit specifically would fix it but adds cost and complexity.
Progress indicator — right now users just see "Processing..." with no feedback on how long it'll take. A server-sent events progress stream from yt-dlp would improve UX significantly.
Caching popular downloads — if 50 people download the same viral TikTok in an hour, processing it 50 times is wasteful. A short TTL cache keyed by URL + format would reduce server load.

Results So Far
Launched 3 weeks ago. Currently at 180+ daily users growing consistently, driven entirely by organic Reddit posts and word of mouth. No paid ads outside of a small TikTok ad test.
The "no ads" positioning has resonated strongly — the most common feedback is people being surprised a downloader site can actually be clean and fast.

Try It
https://dltkk.to — free, no signup, works on any device.
Built with Node.js, Express, yt-dlp, and ffmpeg. Happy to answer any questions about the implementation.

Top comments (3)

Collapse
 
xxsazz profile image
xxsazz • Edited
Thank you for this awesome tool!
Enter fullscreen mode Exit fullscreen mode
Collapse
 
john_jewskiz profile image
john jewski

no problem man!

Collapse
 
thiago_scoti profile image
Thiago De Mattia Scoti

dont work on udemy?