Universal Media Extractor & Link Resolver for Node.js.
Resolve direct media links, unshorten intermediate links, and extract downloadable streams across 20+ platforms.
TikTok β’ Instagram β’ YouTube β’ Spotify β’ Twitter / X β’ Facebook β’ SoundCloud β’ Pinterest β’ Apple Music β’ Bilibili β’ Douyin β’ Bandcamp β’ Threads β’ Pixiv β’ RedNote β’ Reddit β’ TeraBox β’ MediaFire β’ Sfile β’ Safelinku β’ Sub2Unlock β’ Rekonise β’ Unshorten
What is scrapr? A lightweight media extractor and link resolver. Pass a social media, streaming, or shortlink URL and get direct downloadable streams (MP4, MP3, files) or destination URLs with structured metadata. Not a heavy web crawler or generic HTML scraping framework.
npm install @coflyn/scraprOr install directly from GitHub:
npm install git+https://github.com/coflyn/scrapr.gitconst { tiktok, twitter } = require("@coflyn/scrapr");
(async () => {
const tiktokRes = await tiktok.snaptik(
"https://www.tiktok.com/@_coflyn/video/7662892911448558865",
);
if (tiktokRes.status) {
console.log("Title:", tiktokRes.result.title);
console.log("Downloads:", tiktokRes.result.downloads);
}
const twitterRes = await twitter.direct(
"https://twitter.com/Interior/status/463440424141459456",
);
if (twitterRes.status) {
console.log("Media URL:", twitterRes.result.downloads[0].url);
}
})();const { bandcamp } = require("@coflyn/scrapr");
(async () => {
// Direct track/album scraping (HTTP first)
const direct = await bandcamp.direct("https://tycho.bandcamp.com/track/awake");
console.log("Direct stream:", direct.result.downloads[0].url);
// Downloader method with direct fallback
const res = await bandcamp.bandcampdownloader(
"https://tycho.bandcamp.com/album/awake",
{ quality: "320" },
);
console.log(`${res.result.trackCount} tracks found`);
})();const { resolver } = require("@coflyn/scrapr");
(async () => {
// Direct file host resolver
const mf = await resolver.mediafire("https://www.mediafire.com/file/w4b1fjoijyug9qz/nix.py");
console.log("MediaFire direct URL:", mf.result.url);
// Social unlock resolvers (auto-resolves target MediaFire/Sfile link by default)
const s2u = await resolver.sub2unlock("https://sub2unlock.io/example");
console.log("Sub2Unlock destination URL:", s2u.result.url);
const rek = await resolver.rekonise("https://rekonise.com/craniums-free-midi-kit-mlpp6");
console.log("Rekonise unlocked URL:", rek.result.url);
// Shortlink & gateway resolvers
const sfl = await resolver.safelinku("https://sfl.gl/eMeqC");
console.log("Safelinku direct file:", sfl.result.url);
const raw = await resolver.unshorten("https://aka.ms/vscode");
console.log("Unshortened URL:", raw.result.url);
})();const { tiktok } = require("@coflyn/scrapr");
async function resolveTikTok(url) {
const fallbacks = [tiktok.snaptik, tiktok.ssstik];
for (const scraper of fallbacks) {
const res = await scraper(url);
if (res.status) return res.result;
}
throw new Error("All TikTok scrapers failed");
}const scrapr = require("@coflyn/scrapr");
const { tiktok, spotify, resolver } = require("@coflyn/scrapr");import scrapr from "@coflyn/scrapr";
import { tiktok, spotify, resolver } = require("@coflyn/scrapr");{
"status": true,
"result": {
"title": "Media Title / Song Name",
"thumbnail": "https://cdn.example.com/cover.jpg",
"type": "video",
"downloads": [
{
"url": "https://cdn.provider.com/file.mp4?expires=123",
"type": "video",
"quality": "720p"
}
]
}
}For youtube.playlist and bandcamp.bandcampdownloader:
{
"status": true,
"result": {
"title": "Playlist or Album Title",
"type": "playlist",
"itemCount": 10,
"items": [
{
"id": "dQw4w9WgXcQ",
"title": "Track / Video Title",
"author": "Artist or Channel Name",
"thumbnail": "https://cdn.example.com/cover.jpg",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
}
]
}
}{
"status": false,
"message": "Error description / platform rate limit message"
}| Platform | Scraper | Avg Time | Reliability | Notes |
|---|---|---|---|---|
| Apple Music | aplmate |
~3-5s | βͺ Medium | Turnstile bypass, sometimes noise |
| Bilibili | direct |
~0.3-0.5s | π’ High | Direct Bilibili view/playurl API |
| Douyin | direct |
~1-2s | π’ High | Direct iesdouyin SSR + ttwid handshake + WAF solver |
snapsave |
~4-8s | π’ High | Packed JS unpacker, dual stream | |
fdown |
~8-15s | π‘ Medium | Puppeteer + Chrome, Cloudflare bypass | |
| SoundCloud | klickaud |
~4-6s | π’ High | Dynamic CSRF + SSE capability grant |
| TikTok | tiktokio |
~1-2s | π’ High | JSON API, rich metadata |
| TikTok | snaptik |
~0.5-2s | π’ High | Challenge-response AES, IP-safe |
| TikTok | ssstik |
~1-2s | π’ High | Axios + Cheerio, lightweight |
| TikTok | savetik |
~5-8s | π’ High | High quality streams, active |
| TikTok | tikdownloader |
~0.5-1s | π’ High | Direct tikdownloader.io extraction |
| YouTube | ytmp3 |
~6-10s | π’ High | Init + poll, reliable |
| YouTube | playlist |
~2-3s | π’ High | Parsed via ytInitialData lockupViewModel |
direct |
~0.5-1s | π’ High | Native embed captioned JSON, zero 3rd party | |
indown |
~1-2s | π’ High | Direct indown.net API, zero Cloudflare block | |
snapsave |
~0.2-1s | π’ High | Obfuscated script unpacker & rapidcdn stream | |
snapinsta |
~10-15s | π’ High | Playwright stealth + auto-detect system Chrome | |
direct |
~0.5-1s | π’ High | Direct page parsing + pinimg extraction | |
pindown |
~1-2s | π’ High | AES-256-CBC challenge solver & dynamic seed | |
| Bandcamp | direct |
~0.5-1s | π’ High | Direct Bandcamp tralbum data & stream extraction |
| Bandcamp | bandcampdownloader |
~1-2s | π’ High | Token CSRF with direct fallback |
| Pixiv | ajax |
~0.4s | π’ High | Official oEmbed + pixiv.re proxy fallback |
| RedNote | direct |
~1-2s | π’ High | SSR state + OpenGraph parsing |
rapidsave |
~1-2s | π’ High | RapidSave video + separate audio stream | |
| TeraBox | sechno |
~1-3s | π’ High | Direct download link + fast m3u8 streaming |
| Resolver | mediafire |
~0.5-1.0s | π’ High | Direct MediaFire button & CDN link resolver |
| Resolver | sfile |
~0.4-0.8s | π’ High | Direct Sfile session & CDN resolver |
| Resolver | sub2unlock |
~0.8-1.5s | π‘ Medium | Supports sub2unlock.io & sub2unlock.com |
| Resolver | rekonise |
~11-13s | π’ High | Action handshake + server timer compliance |
| Resolver | safelinku |
~2.5-4s | π’ High | Gateway API handshake & file auto-resolve |
| Resolver | unshorten |
~0.5-1.5s | π’ High | HTTP redirection chain & file auto-resolve |
| Spotify | spotisaver |
~2s | π’ High | Fast signature handshake, direct MP3 stream |
| Spotify | spotidown |
~2-3s | π’ High | Token injection, supports albums/tracks |
| Spotify | spotmate |
~4-6s | π’ High | Spotimate API with userverify handshake |
| Spotify | soundloaders |
~3-5s | π’ High | Migrated to spotimate.app multipart stream |
| Twitter / X | direct |
~0.3-1s | π’ High | Direct FxTwitter CDN resolver |
| Twitter / X | tweeload |
~2-4s | π’ High | Multi-quality |
| Twitter / X | tvd |
~0.5-2s | π’ High | TVD with direct FxTwitter fallback |
| Twitter / X | savetwt |
~0.5-2s | π’ High | SaveTWT with x.com normalization & fallback |
| Threads | threadster |
~2-4s | π‘ Medium | Threadster API with JWT token decoding & cookie session |
| Error | Likely Cause | Fix |
|---|---|---|
Request failed with status code 4xx |
Upstream changed or blocked | Try alternate scraper |
Could not extract CSRF token |
Page structure changed | Report issue |
No download links found |
Private content or dead link | Check URL accessibility |
socket hang up / ETIMEDOUT |
Network issue / rate limit | Retry with delay or proxy |
Cannot read properties of undefined |
Parser mismatch | Report issue |
const axios = require("axios");
axios.defaults.timeout = 30000; // 30sconst axios = require("axios");
const HttpsProxyAgent = require("https-proxy-agent");
axios.defaults.httpsAgent = new HttpsProxyAgent("http://proxy:8080");scrapr/
βββ index.js # Entry point: exports all platform modules
βββ lib/
βββ <platform>/ # Platform namespace (e.g. tiktok, instagram)
βββ index.js # Platform export aggregator
βββ <method>/ # Scraper implementation
βββ index.js # Exports { scrape }
- Node.js >= 16.x
- npm or yarn
| Dependency | Version | Purpose |
|---|---|---|
axios |
^1.7.0 | HTTP client |
cheerio |
^1.0.0 | HTML parsing & DOM traversal |
Most scrapers use lightweight HTTP + DOM parsing only. Some require a browser for Cloudflare bypass:
# For savetik (TikTok) & fdown (Facebook): requires Google Chrome installed
npm install puppeteer-core
# For snapinsta (Instagram)
npm install playwright-extra puppeteer-extra-plugin-stealth
npm install playwrightContributions are welcome. Please read CONTRIBUTING.md for architecture details, response schemas, and verification instructions.
All contributors must adhere to CODE_OF_CONDUCT.md.
For security vulnerabilities and responsible disclosure, please refer to SECURITY.md.
If you encounter any issues, broken scrapers, or request errors (which can happen frequently as source web pages update their endpoints), please open an issue.
You can also open an issue to request support for a new platform or scraper.
This project is an open-source library that parses publicly available data. Source websites and third-party APIs can modify their markup, anti-bot mechanisms, or rate limits at any time.
If you are the owner, operator, or authorized representative of any website or service supported in this project and would like your service removed from this repository, please open an issue with the title prefix [Removal Request]. We respect website operators and will promptly honor removal requests.
MIT - (c) 2026 coflyn