social-dl
v1.3.6
Published
Social media downloader with direct extractors and Spotify metadata with confidence-matched track audio
Maintainers
Readme
SOCIAL MEDIA SCRAPPER ⚉
brought to you by CRYSNOVA_AI
social-dl — The last downloader you'll ever need
Direct social-media downloader for YouTube, TikTok, Facebook, Instagram, Twitter/X, Pinterest, CapCut, and Spotify links. Spotify metadata is read from public embeds; full audio uses a separately matched source, never a Spotify stream.

Why social-dl?
| Capability | social-dl | Proxy downloader API | |---|---:|---:| | Direct CDN extraction | Yes | No | | Depends on a third-party API staying online | No | Yes | | API key required | No | Often | | Open source | No — proprietary | Varies |
Install
npm install social-dlsocial-dl uses the verified yt-dlp executable bundled with the package, including on Android/Termux. If yt-dlp cannot retrieve a source, social-dl tries Cobalt-compatible and PrexzyAPIs fallbacks. Node.js 18 or newer is required. License and third-party notices for the bundled release are included under licenses/yt-dlp/.
Pinned yt-dlp engine
yt-dlp is vendored, pinned, and verified: it ships inside the package instead of being resolved at runtime.
| Platform | Vendored binary | Integrity |
|---|---|---|
| Linux | bin/yt-dlp | verified against SHA2-256SUMS |
| macOS | bin/yt-dlp_macos | verified against SHA2-256SUMS |
| Windows | bin/yt-dlp.exe | verified against SHA2-256SUMS |
The pinned release is recorded in licenses/yt-dlp/VERSION, in the official licenses/yt-dlp/SHA2-256SUMS, and in the YTDLP_VERSION / YTDLP_SHA256 constants of src/core/binary.js — all three are kept in sync.
The runtime never downloads or discovers yt-dlp. It does not fetch from GitHub, search PATH, read YTDLP_PATH, use yt-dlp-exec, or install an external downloader. It resolves the executable vendored in this package and fails loudly if that file is missing.
Keeping yt-dlp current
Updates are prepared automatically and reviewed by a human — never silently applied:
.github/workflows/update-ytdlp.ymlruns on the first day of every month, and on demand throughworkflow_dispatch.- It resolves the latest stable yt-dlp release, rejecting drafts, prereleases, and tags that are not in
YYYY.MM.DDform. - Every binary is verified against that release's official
SHA2-256SUMSbefore anything is replaced, and the officialLICENSEandTHIRD_PARTY_LICENSES.txtare refreshed from the same tag. - The verified result is pushed to an
automation/yt-dlp-<version>branch and opened as a reviewable pull request. Nothing is committed tomainautomatically, and the pull request is never auto-merged.
Run the same update locally with:
node scripts/update-ytdlp.mjsThe updater uses only Node.js built-ins, writes every file atomically (temp file plus rename) so a failed run cannot leave a partial binary behind, preserves the executable bit on the Linux and macOS binaries, and is idempotent — re-running it against an already-pinned release leaves the working tree untouched.
Termux setup
pkg update
pkg install nodejs ffmpeg python
npm install -g social-dl
npx social-dl doctorIf a platform blocks the network, retry with a permitted cookie export or proxy rather than repeatedly hammering the provider. Keep yt-dlp and FFmpeg current through the package release; social-dl pins its bundled yt-dlp engine for reproducible behavior.
CLI
npx social-dl https://youtu.be/BJs3DBrMTSc
npx social-dl https://youtu.be/BJs3DBrMTSc --mp3 -o audio.m4a
npx social-dl https://facebook.com/share/r/xxx/ --json
npx social-dl https://www.tiktok.com/@user/video/123 --no-watermark
npx social-dl https://www.instagram.com/reel/CODE/ --cookies ~/cookies.txt -o instagram.mp4
npx social-dl https://www.tiktok.com/@user/video/123 --cookies-from-browser chrome -o tiktok.mp4
npx social-dl https://open.spotify.com/track/0wf9rSX8ds3yEI2gf2QdPs -o dreams.mp3
npx social-dl https://open.spotify.com/track/0wf9rSX8ds3yEI2gf2QdPs --json
npx social-dl doctorEasy format and quality selection
Every supported platform uses the same command shape. mp4 is the default video mode; mp3 uses FFmpeg to extract audio when the source provides a compatible audio stream.
# Interactive Termux-friendly menu
npx social-dl
# Direct commands
npx social-dl "URL" --format mp4 --quality best -o video.mp4
npx social-dl "URL" --format mp4 --quality 720p -o video.mp4
npx social-dl "URL" --format mp3 -o audio.mp3
npx social-dl "URL" --format mp4 --quality 720p --safe -o video.mp4
# Equivalent shorthand for MP3
npx social-dl "URL" --mp3 -o audio.mp3--quality best|720p|480p applies to video downloads when the provider exposes selectable formats. --safe/--safe-mode adds conservative yt-dlp pacing (3–6 second sleeps and a 5M rate limit); it reduces request pressure but is not an anti-bot bypass. Use cookies or a permitted proxy for content requiring authentication.
Spotify track links
social-dl reads Spotify track metadata directly from Spotify's public embed page and does not depend on spotify.xwolf.space, a Spotify bearer token, or a developer account. For a full-length MP3, it searches the bundled yt-dlp-supported source using the Spotify title, artist, and duration, and saves only a sufficiently close candidate. Audio retrieval tries the primary yt-dlp path, the package's generic fallbacks, then the existing youtubeMp3Save() path; if that returns native M4A/Opus audio, FFmpeg converts it to MP3. The result keeps platform: "spotify" for the input link and includes matchedSource/audioSource so developers can see where the audio actually came from. If the match is uncertain, it raises NoConfidentMatchError (NO_CONFIDENT_MATCH) and downloads nothing. This is not a full-track Spotify stream; it can fail if the external result is unavailable or requires permitted cookies. A previewUrl, when Spotify supplies one, is only preview metadata and is not used as a substitute for the full track.
import { spotifyMetadata, spotifyDl, spotifySave } from 'social-dl/spotify';
const metadata = await spotifyMetadata('https://open.spotify.com/track/0wf9rSX8ds3yEI2gf2QdPs');
const resolved = await spotifyDl(metadata.originalUrl); // metadata + validated match
await spotifySave(metadata.originalUrl, './dreams.mp3');Run npx social-dl doctor to verify Node.js, FFmpeg, the pinned yt-dlp binary/version, and provider reachability before troubleshooting a download. Use npx social-dl maintenance for the interactive engine update and safe cache reset menu; reset never deletes downloaded media. --format mp3 requires FFmpeg; if a platform only exposes a ready-made media file, social-dl keeps the provider’s native media instead of pretending it can convert it. --json shows normalized metadata and available formats before saving, while --no-watermark requests a no-watermark variant when the provider supports one.
For login-required Instagram or TikTok posts, pass an exported cookie file with --cookies path/to/cookies.txt or use --cookies-from-browser chrome, firefox, edge, or brave. YouTube may reject datacenter IPs; doctor reports this as BOT_DETECTED.
Library
import { universalDl, universalSave, universalStream } from 'social-dl';
const data = await universalDl('https://youtu.be/BJs3DBrMTSc');
await universalSave('https://youtu.be/BJs3DBrMTSc', './video.mp4');Platform-specific library examples
Every platform also exposes its own xxxDl() and xxxSave() functions. Each Dl() call returns normalized metadata and direct CDN formats; each Save() call downloads the selected format.
import { facebookDl, facebookSave } from 'social-dl/facebook';
const facebook = await facebookDl('https://www.facebook.com/reel/1234567890/');
await facebookSave('https://www.facebook.com/reel/1234567890/', './facebook.mp4', 'HD');YouTube video
import { youtubeDl, youtubeSave } from 'social-dl/youtube';
const youtube = await youtubeDl('https://youtu.be/BJs3DBrMTSc');
await youtubeSave('https://youtu.be/BJs3DBrMTSc', './youtube.mp4', '720p');YouTube audio
import { youtubeMp3Dl, youtubeMp3Save } from 'social-dl/ytmp3';
const audio = await youtubeMp3Dl('https://youtu.be/BJs3DBrMTSc');
await youtubeMp3Save('https://youtu.be/BJs3DBrMTSc', './audio.m4a');import { instagramDl, instagramSave } from 'social-dl/instagram';
const instagram = await instagramDl('https://www.instagram.com/reel/CODE/', { cookiesPath: './cookies.txt' });
await instagramSave('https://www.instagram.com/reel/CODE/', './instagram.mp4', 'best', { cookiesPath: './cookies.txt' });TikTok
import { tiktokDl, tiktokSave } from 'social-dl/tiktok';
const tiktok = await tiktokDl('https://www.tiktok.com/@user/video/1234567890123456789', { cookiesFromBrowser: 'chrome' });
await tiktokSave('https://www.tiktok.com/@user/video/1234567890123456789', './tiktok.mp4', 'NOWM', { cookiesFromBrowser: 'chrome' });Twitter/X
import { twitterDl, twitterSave } from 'social-dl/twitter';
const tweet = await twitterDl('https://x.com/user/status/1851234567890');
await twitterSave('https://x.com/user/status/1851234567890', './twitter.mp4');import { pinterestDl, pinterestSave } from 'social-dl/pinterest';
const pin = await pinterestDl('https://www.pinterest.com/pin/1234567890/');
await pinterestSave('https://www.pinterest.com/pin/1234567890/', './pinterest.mp4');CapCut
import { capcutDl, capcutSave } from 'social-dl/capcut';
const template = await capcutDl('https://www.capcut.com/template-detail/1234567890');
await capcutSave('https://www.capcut.com/template-detail/1234567890', './capcut.mp4');Express/Next.js streaming
const { stream, contentType, filename } = await universalStream(url);
res.setHeader('Content-Type', contentType);
res.setHeader('Content-Disposition', `inline; filename="${filename}"`);
Readable.fromWeb(stream).pipe(res);[NEW] Spotify
import { spotifyDl, spotifySave } from 'social-dl/spotify';
const template = await spotifyDl('https://open.spotify.com/track/0wf9rSX8ds3yEI2gf2QdPs');
await spotifySave('https://open.spotify.com/track/0wf9rSX8ds3yEI2gf2QdPs', './spotify.mp3');Platforms
| Platform | Example |
|---|---|
| Facebook | https://www.facebook.com/reel/1234567890/ |
| YouTube | https://youtu.be/BJs3DBrMTSc |
| Instagram | https://www.instagram.com/reel/CODE/ |
| TikTok | https://www.tiktok.com/@user/video/123 |
| Twitter/X | https://x.com/user/status/123 |
| Pinterest | https://www.pinterest.com/pin/1234567890/ |
| CapCut | https://www.capcut.com/template-detail/1234567890 |
| YouTube audio | Same YouTube URLs with { audioOnly: true } or --mp3 |
| Spotify track | https://open.spotify.com/track/0wf9rSX8ds3yEI2gf2QdPs (MP3; match-checked) |
API reference
universalDl(url, { audioOnly, quality, cookiesPath, cookiesFromBrowser })— return normalized direct-CDN formats.universalSave(url, destination, { audioOnly, quality, noWatermark, cookiesPath, cookiesFromBrowser, safeMode })— save a selected format.safeMode: trueenables conservative pacing for yt-dlp.audioOnly: trueis the library equivalent of--format mp3.- The shared CLI works across YouTube, TikTok, Facebook, Instagram, Twitter/X, Pinterest, and CapCut. Video quality and MP3 conversion depend on the formats and FFmpeg support available for each source.
universalStream(url, options)— return a WebReadableStreamfor piping.spotifyMetadata(url)— read public Spotify embed metadata for a track, album, artist, or playlist without using the WOLF API.spotifyDl(url, options)— return track metadata plus a conservative separate-source audio match;formatsis empty because the match is not a Spotify CDN URL.spotifySave(url, destination, quality, options)— download the validated track match as MP3; may require FFmpeg and/or permitted source cookies.doctor({ log })— test provider reachability, Node, FFmpeg, and the bundled yt-dlp engine.npx social-dl maintenance— interactively update the yt-dlp engine or reset only generated cache/cookie state; downloaded media is preserved.- Every platform exports
xxxDl()andxxxSave().
Fallback Credits
social-dl uses multiple fallback services to improve download reliability:
- PrexzyAPIs.com
- Cobalt-compatible endpoints
Fallbacks are used when the primary yt-dlp path cannot retrieve media. Third-party services may be unavailable or change behavior.
Set SOCIAL_DL_PROXY to use a proxy for the primary yt-dlp request. The fallback services do not require this variable. For YouTube bot checks, provide an exported Netscape cookie file with --cookies path/to/youtube-cookies.txt, use --cookies-from-browser chrome, or set SOCIAL_DL_YOUTUBE_COOKIES / SOCIAL_DL_YOUTUBE_COOKIES_FROM_BROWSER. social-dl tries multiple yt-dlp YouTube clients before using Cobalt and Prexzy; third-party services can still be unavailable or block the source.
Support the creator
If social-dl helps your projects, support development through any of these options:
Bank transfer (Nigeria)
- Bank: First Bank Nigeria
- Account name: CRYSTAL-LEVI UZOUKWU
- Account number:
3230171045
Telegram Stars
Use the bot donation shortcut: @CODYEBOT — Donate. You can also reach @crysnovax or @plogme.
USDT
- Network: BNB Smart Chain (BEP-20)
- Address:
0xa1140712e9a1d459fc32c7d2f7e33e18790db835
Confirm that your wallet is set to BEP-20 / BNB Smart Chain before sending. Run npx social-dl support to print these details in the terminal.
Scan to support

If the QR image does not render, open the direct image link: https://cdn.crysnova.qzz.io/files/1790796246940-eede6a21-3ee8-45d3-94ad-2fcd0fa82525.jpeg.
Contact and community
For support, updates, and community help:
- WhatsApp channel 1
- WhatsApp channel 2
- Telegram channel — CRYSNOVA AI
- CRYSNOVA platform
- Cody AI WhatsApp bot repository
Run npx social-dl support to print donation and contact links in the terminal.
Error handling
Handle BotDetectedError for provider anti-automation blocks, PrivateError for login/private content, NotFoundError for missing media, NoConfidentMatchError when a Spotify audio match is not strong enough, and UnsupportedError for unsupported URLs.
Demo
Demo video coming in 1.0.0 — npx becomes available after this 0.9.0 pre-launch.
Release checklist
Before publishing a new npm version:
npm test
npm pack --dry-run
npx social-dl doctorThe package requires Node.js 18 or newer. MP3 conversion requires FFmpeg. Provider availability can change independently of social-dl, so login-required or blocked sources should be tested with permitted cookies or a proxy.
License
Proprietary license. See LICENSE.
created and maintained by crysnovax • @plogme please this has no promotional intent or unofficial bridge of any sort. do not missus this package.
