| name | headless-youtube |
| description | Read YouTube Shorts and videos from terminal via Chrome CDP and youtubei JSON interception. Tech videos only by default. Anti-doom-scroll: hard caps on results (max 50) and scroll iterations (max 8), force-muted/paused video element, STOP footer after every fetch. Zero API keys. Zero mutations. 3-layer read-only enforcement. Supports shorts, search, channel, trending, home, subscriptions, watch, playlist modes with language filtering and JSON output. Built on the same architecture as headless-twitter and headless-instagram. Use when asked to fetch youtube videos, scan youtube shorts, search youtube, monitor a channel, or pipe video metadata to scripts — without opening the YouTube app and getting sucked into the feed.
|
headless-youtube
Read YouTube Shorts and videos from your terminal. Connects to your logged-in Chrome via CDP. Intercepts the internal youtubei/v1/* JSON responses and parses ytInitialData. No DOM scraping, no clicks, no API keys, no browser downloads. Strictly read-only. Filters for tech videos by default. Built explicitly to stop doom-scrolling — fetch the metadata, decide what's worth your time, do not open YouTube.
When to Use
- User asks to "fetch youtube videos", "scan shorts", "search youtube", "tech youtube"
- User wants to discover new tech tutorials/launches/talks without opening YouTube
- User needs video metadata piped into scripts or LLM context
- User asks "what's interesting on youtube today", "what's trending in tech videos"
- User explicitly says they want to avoid doom-scrolling but still wants the signal
Prerequisites
which headless-youtube || npm install -g headless-youtube
No browser download needed. Uses your existing Chrome installation.
Quick Start
headless-youtube youtube shorts '' 15 --lang en
headless-youtube youtube search "rust async tutorial" 10
headless-youtube youtube channel fireship 10
headless-youtube youtube channel @theprimeagen 10
headless-youtube youtube trending '' 15 --lang en
headless-youtube youtube home '' 15
headless-youtube youtube subscriptions '' 15
headless-youtube youtube watch dQw4w9WgXcQ 1 --json
headless-youtube youtube shorts '' 30 --no-filter
headless-youtube youtube search "ai agents" 20 --json --lang en
Modes
| Mode | Command |
|---|
| Shorts feed | headless-youtube youtube shorts '' LIMIT --lang en |
| Search | headless-youtube youtube search "QUERY" LIMIT --lang en |
| Channel | headless-youtube youtube channel "@username" LIMIT --lang en |
| Trending | headless-youtube youtube trending '' LIMIT --lang en |
| Home feed | headless-youtube youtube home '' LIMIT --lang en |
| Subscriptions | headless-youtube youtube subscriptions '' LIMIT --lang en |
| Single video | headless-youtube youtube watch VIDEO_ID 1 --json |
| Playlist | headless-youtube youtube playlist PLAYLIST_ID LIMIT |
| JSON output | headless-youtube youtube search "AI" 5 --json |
| List mode | headless-youtube youtube shorts '' 5 --no-card |
| All videos | headless-youtube youtube shorts '' 20 --no-filter |
Options
| Flag | Description | Default |
|---|
--lang LANG | Filter by language (en, es, ja, hi, gu, zh, ko...) | all |
--cdp-url URL | CDP endpoint | http://localhost:9222 |
--browser NAME | Browser: chrome | chromium | brave | auto-detect |
--json | Machine-readable JSON output | TUI (Card) |
--no-card | Standard list-style output | off |
--no-filter | Skip tech filter, return all videos | tech only |
--max-scrolls N | Scroll iterations (hard max: 8) | 4 |
--debug | Show endpoints and extraction details | off |
--help | Show help | — |
Anti-Doom-Scroll Guarantees
This is the whole point of the skill. Never disable these.
| Guard | Behavior |
|---|
| Hard result cap | LIMIT is silently clamped to 50, even if you ask for 1000. |
| Hard scroll cap | --max-scrolls is clamped to 8. No "scroll forever" mode. |
| Forced mute/pause | Every <video> element is muted and paused on loadedmetadata. |
| No watch UI | Output is text + URLs only. No autoplay, no thumbnails, no clicks. |
| STOP footer | Every fetch ends with a "STOP. Close terminal." reminder. |
| Read-only | Cannot like, subscribe, comment, share, or report — by design. |
Output
TUI (default — Card mode)
┌──────────────────────────────────────────────────────────────────────────┐
│ ▶ video #1 Fireship [P0] AI/LLM │
│ ▶ 412.0k views ⏱ 8:24 2 weeks ago │
│ │
│ This new agent framework just dropped — it replaces LangChain │
│ for tool-use heavy workflows │
│ │
│ → https://www.youtube.com/watch?v=abc123 │
└──────────────────────────────────────────────────────────────────────────┘
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
STOP. 15 items read. Close terminal. Do not open YouTube.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
JSON (--json)
{
"source": "youtube",
"mode": "search",
"query": "rust async tutorial",
"count": 10,
"videos": [{
"id": "abc123",
"kind": "video",
"title": "Rust async tutorial — 30 min crash course",
"channel": "Jon Gjengset",
"desc": "Walks through tokio runtime, futures, and select!...",
"lang": "en",
"views": 412000,
"viewsText": "412K views",
"duration": 504,
"lengthText": "8:24",
"published": "2 weeks ago",
"isLive": false,
"url": "https://www.youtube.com/watch?v=abc123"
}]
}
kind is "short" for Shorts (URL is /shorts/ID) and "video" otherwise.
How It Works
- Connects to your running Chrome via CDP (auto-launches if needed)
- Installs 3-layer read-only guards (network + DOM + code)
- Opens new tab, navigates to the target YouTube URL
- Pulls
window.ytInitialData for first-paint videos
- Intercepts
youtubei/v1/* JSON responses for paginated/scroll-loaded videos
- Auto-scrolls a bounded number of times (≤8)
- Walks the captured JSON for known renderer shapes (
videoRenderer, shortsLockupViewModel, reelItemRenderer, etc.)
- Filters by language if specified
- Filters for tech-intro content (unless
--no-filter)
- Outputs TUI or JSON
- Closes tab. Chrome stays running.
Tech Filter
Two-signal approach mirroring headless-instagram:
Signal 1 — "New thing" / "Learn this" keywords: launched, released, shipped, introducing, new tool/framework/library/api/feature/release/version/update/model, vN.N, open-sourced, game changer, you need to try, replaces my/your/the, better than X, stop using, tutorial, crash course, deep dive, explained, walkthrough.
Signal 2 — Tech domain keywords: react/vue/svelte/angular/next/nuxt/remix/astro/flutter, python/javascript/typescript/rust/go/swift/kotlin/c++/zig, api/sdk/cli/npm/pip/cargo/docker/k8s/wasm, ai/llm/gpt/claude/openai/anthropic/gemini/llama/mistral, github/vscode/cursor/copilot/vercel/supabase/firebase/neovim, database/backend/frontend/fullstack/distributed, machine learning/deep learning/transformer/rag/agent, cloud/aws/gcp/azure/serverless/lambda/terraform, linux/kernel/systems/compiler/gpu/cuda/ebpf/risc-v.
A video passes the filter when it has BOTH signals, OR is from a known tech channel (Fireship, ThePrimeagen, Computerphile, Two Minute Papers, Lex Fridman, Asianometry, Low Level Learning, etc.), OR has 2+ domain hits. Use --no-filter to get everything.
Read-Only Enforcement
Layer 1 — Network: Block POST/PUT/DELETE/PATCH and youtubei mutation paths
(like, comment, subscription, feedback, share, playlist edit,
log_event, watchtime, qoe stats, account switcher)
Layer 2 — DOM: Freeze click/submit/input/keydown/pointer/touch/mouse events
Layer 3 — Code: Zero page.click(), page.fill(), page.type() calls
Plus: every <video> is force-muted and paused on loadedmetadata
Cannot like, dislike, subscribe, comment, share, add-to-playlist, or report. By design, not by promise.
Agent Instructions
- Check if installed:
which headless-youtube
- If missing:
npm install -g headless-youtube (or npm install in this skill dir, then npm link)
- Default to
--lang en unless user specifies otherwise (Om also reads gu and hi)
- Default to tech filter ON unless user asks for "all videos" or "general feed"
- Default LIMIT is 15. Never bump it past 50 even if user asks — anti-doom-scroll is the point.
- Do NOT use
--json unless user explicitly asks for raw JSON or you're piping into secondmem / another script.
- After fetching, summarize results grouped by tier (P0 → P3) using the same TUI card style as headless-twitter. P0 = "new thing + tech domain", P1 = "tech domain + >100k views", P2 = "tech domain only", P3 = everything else.
- Surface action items: P0 video URLs go into an ACTION ITEMS box at the bottom (papers/repos referenced in description, or "watch this on the train").
- End every response with the STOP reminder. The user invoked this skill because they want to avoid YouTube.
Cross-Reference With Other Skills
| Use case | Pipeline |
|---|
| Daily tech intel | headless-youtube youtube subscriptions '' 15 --json → secondmem ingest |
| Topic deep-dive | headless-twitter for hot takes + headless-youtube for tutorials + arXiv via tech-discovery |
| Launch radar | headless-youtube youtube search "just shipped" 10 + headless-instagram instagram reels '' 15 |
| Catch-up digest | feed into om-feed/secondmem-persistent for ranking and storage |
Notes
- Single dependency:
puppeteer-core (no browser download)
- Same CDP connection as headless-twitter and headless-instagram — shares the browser session
- Chrome stays running between commands for instant reconnect
- Hard max 50 videos per request (anti-doom-scroll)
- Hard max 8 scroll iterations per request (anti-doom-scroll)
- Linux/macOS supported. Windows needs manual Chrome CDP launch.
watch mode returns metadata for a single video only — does NOT play it.