npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

streamline-md

v1.2.0

Published

Streamline by FlameonLabs - an open-source WebUI for yt-dlp.

Readme

Streamline

A beautiful, open-source WebUI for yt-dlp

Download videos and audio from 1000+ platforms — YouTube, TikTok, Instagram, Twitter/X, Facebook, and more.

Version License Bun

Streamline Screenshot


✨ Features

  • 1000+ supported platforms via yt-dlp — YouTube, TikTok, Instagram, Twitter/X, SoundCloud, Bandcamp, and hundreds more
  • Format picker — choose resolution (4K, 1080p, 720p, 480p) or audio-only; defaults to best MP4
  • Download queue — sequential queue with drag-to-reorder, pause/resume, and retry
  • Live logs — real-time yt-dlp stdout/stderr streamed to the terminal panel via WebSocket
  • Download history — persistent log of all past downloads with file-open shortcut
  • Playlist support — bulk-select individual playlist entries before downloading
  • Advanced options — subtitles, thumbnails, metadata embedding, SponsorBlock, rate limiting, custom yt-dlp flags
  • Cookie authentication — upload browser cookies for age-restricted or members-only content
  • Dark & light theme — toggle in the sidebar; preference persisted to localStorage
  • Desktop notifications — browser notifications on download complete

🚀 Quick Start

Prerequisites

| Tool | Version | Notes | |------|---------|-------| | Bun | >= 1.1 | JavaScript runtime + package manager | | Python | >= 3.9 | Required for yt-dlp | | yt-dlp | latest | Auto-installed on first run | | ffmpeg | any | Auto-installed via npm package |

Install & Run

# Install (downloads yt-dlp and ffmpeg automatically)
npx streamline

# Or install globally:
npm install -g streamline
streamline

The app opens at http://localhost:7979

Development Mode

git clone https://github.com/flameonlabs/streamline
cd streamline
bun install
bun run dev
  • Frontend: http://localhost:5173
  • Backend: http://localhost:7979
  • WebSocket: ws://localhost:7979/ws

🖥️ Usage

  1. Paste a URL into the input bar — metadata is fetched automatically
  2. Pick a format in the right panel (defaults to best MP4)
  3. Click Download — the video moves to the queue immediately
  4. Watch progress in the Queue panel and live yt-dlp output in the Logs panel
  5. Open the file when complete using the folder icon

Batch Downloads

Click Batch next to the URL bar, paste multiple URLs (one per line or comma-separated), then click Download All.

Playlists

Paste a playlist URL — Streamline detects it automatically and shows a checklist. Select individual entries, then click Download Selected.


⚙️ Settings

General

| Setting | Default | Description | | --- | --- | --- | | Output folder | ~/Downloads/Streamline | Where completed files are saved | | Filename template | %(title)s.%(ext)s | yt-dlp output template |

Download Options

| Option | Default | | --- | --- | | Video format | MP4 | | Audio format (audio-only) | MP3 | | Subtitles | Off | | Embed metadata | Off | | SponsorBlock | Off | | Concurrent fragments | 8 | | Rate limit | Unlimited | | Custom yt-dlp flags | - |

Cookie Authentication

For age-restricted, members-only, or login-required content, export cookies from your browser using the cookies.txt format and upload in Settings → Cookie Authentication.

Environment

If yt-dlp or ffmpeg is not detected, go to Settings → Environment and click Repair to re-provision all dependencies.


🏗️ Architecture

streamline/
├── server/                  # Bun + Elysia backend
│   ├── index.js             # Server entry, WebSocket upgrade
│   ├── routes/              # REST API routes
│   │   ├── download.js      # Queue management endpoints
│   │   ├── formats.js       # yt-dlp metadata fetch
│   │   ├── env.js           # Environment status + repair
│   │   ├── history.js       # Download history
│   │   └── cookies.js       # Cookie file management
│   ├── services/
│   │   ├── ytdlp.js         # yt-dlp process management + progress parsing
│   │   ├── queue.js         # Sequential download queue
│   │   ├── environment.js   # Tool resolution (yt-dlp, ffmpeg, bun)
│   │   ├── history.js       # Persistent history (JSON file)
│   │   ├── cookies.js       # Cookie file storage
│   │   └── temp.js          # Temp directory lifecycle management
│   └── ws/
│       └── handler.js       # WebSocket client manager + broadcast
│
├── src/                     # React frontend
│   ├── App.jsx
│   ├── pages/
│   │   ├── DownloadPage.jsx
│   │   ├── HistoryPage.jsx
│   │   └── SettingsPage.jsx
│   ├── components/          # All UI components
│   ├── hooks/
│   │   ├── useStore.js      # Zustand global state
│   │   └── useWebSocket.js  # WS client + polling fallback
│   └── lib/utils.js
│
├── bin/streamline.js        # npx entry point
├── scripts/
│   └── provision.js         # yt-dlp + ffmpeg setup
└── dist/                    # Built frontend (generated)

Data Flow

User pastes URL
  → GET /api/formats → yt-dlp --dump-json → media info displayed

User clicks Download
  → POST /api/download → DownloadQueue.add()
  → processNext() → ytdlp.startDownload()
  → stdout/stderr piped → onProgress / onLog callbacks
  → queue.emit({ type: 'progress'|'log', ... })
  → wsManager.broadcast() → WebSocket → useWebSocket.js
  → Zustand store.updateDownload() / appendLog()
  → React re-render → progress bar + live logs update

🔌 API Reference

| Method | Endpoint | Description | | --- | --- | --- | | GET | /api/formats?url= | Fetch media metadata and formats | | POST | /api/download | Queue a new download | | GET | /api/download/status | Get current queue state | | DELETE | /api/download/:id | Cancel/remove a download | | POST | /api/download/retry | Retry a failed download | | PATCH | /api/download/reorder | Reorder queue | | POST | /api/download/open-folder | Open file location in OS | | GET | /api/history | Get download history | | DELETE | /api/history | Clear all history | | GET | /api/env | Get environment status | | POST | /api/env/repair | Re-provision dependencies | | WS | /ws | Real-time progress + log events |

WebSocket Events (server → client)

| Event type | Fields | Description | | --- | --- | --- | | started | downloadId | Download process spawned | | progress | downloadId, progress, speed, eta, filesize, line | Progress update | | merging | downloadId, line | ffmpeg merge started | | complete | downloadId, filepath, title | Download finished | | error | downloadId, error | Download failed | | log | downloadId, line | Raw yt-dlp output line | | paused | downloadId, progress | Download paused | | env_status | data | Environment health update | | provision_log | line | Provisioning log line | | provision_done | success | Provisioning complete |


🛠️ Troubleshooting

Downloads stuck at 0%

  • Check Settings → Environment — yt-dlp and ffmpeg must both show OK
  • For fragmented videos (YouTube 1080p+), progress updates in chunks — this is normal
  • Open the Live Logs panel to see raw yt-dlp output

"Sign in to confirm you're not a bot"

  • Upload YouTube cookies in Settings → Cookie Authentication
  • Export cookies from a fresh private/incognito YouTube session

No Live Logs appearing

  • Ensure the WebSocket indicator (bottom of sidebar) shows connected
  • Try refreshing — the WS auto-reconnects with exponential backoff

yt-dlp binary not found

  • Run repair: Settings → Environment → Repair
  • Or manually: pip install -U yt-dlp

ffmpeg not found / merge errors

  • ffmpeg is bundled via npm. Run bun install to reinstall
  • Or set a custom path in Settings → Environment

🤝 Contributing

Contributions are welcome! Please read the contributing guidelines and open an issue before submitting large PRs.

bun run test          # Run all tests
bun run test:server   # Server-side tests only
bun run build         # Production build

📄 License

MIT © FlameonLabs