Archive your channel and share a personal copy with family — Node.js, local files, no database.
Download your videos, browse them in an offline viewer, and hand off a folder family can open offline. No sign-in, no streaming, no setup on their side.
Built for creators who want parents, grandparents, or anyone non-technical to watch their channel offline.
- yt-dlp archiver — downloads videos with metadata, thumbnails, and optional subtitles
- Incremental downloads —
downloads/archive.txtledger skips videos you already have - Portable static viewer — works via
file://or the local preview server at http://localhost:8098/ - Search — filter by title, description, and tags
- Shorts UI — portrait player, Shorts badges, dedicated tab, and “More Shorts” rail
- HTTP range support — seek within videos when using the preview server
- Export tool — backup copies with metadata sidecars; optional ffmpeg re-encode
- Light / dark theme — toggle in the top bar; preference saved in the browser
- Plain Node.js
httpserver with static HTML + JS (no framework or build step)
Open a terminal in the pigeon-cache folder. Replace the URL with your own channel.
Mac:
make install
make download N=10 URL="https://www.youtube.com/@YourChannel/shorts"
make serveWindows:
node --version
yt-dlp --version
node scripts/download.js --max 10 "https://www.youtube.com/@YourChannel/shorts"
npm startOpen http://localhost:8098/.
Or use Make (Mac):
make help # list all commands
make install # Node.js, yt-dlp, ffmpeg
make download N=10 URL="https://www.youtube.com/@YourChannel/shorts"
make manifest # rebuild video index
make serve # foreground preview server
make start # background server
make stop
make restart
make status
make open-offline # open viewer from disk (file://)
make dev # foreground with file watch- Node.js 18+ — nodejs.org
- yt-dlp — downloads videos from your channel
- ffmpeg (recommended) — best quality merges and export re-encode
Mac — brew install node yt-dlp ffmpeg or make install
Windows — winget install OpenJS.NodeJS.LTS yt-dlp.yt-dlp Gyan.FFmpeg, or install manually from the links above. Restart your terminal after installing.
After downloading:
- Double-click
index.htmlto confirm videos play — Mac:make open-offline. - Copy the entire
pigeon-cachefolder to a USB drive, external disk, or cloud folder. - Tell them: “Double-click index.html to watch.”
On their computer they only need step 3 — no terminal, no install, no internet.
Edit config.json before downloading. Settings control what family sees in the viewer and how downloads and exports behave.
| Field | Description |
|---|---|
channel_url |
Default channel, playlist, or Shorts URL |
channel_name |
Title in the viewer header — use a friendly name for family |
channel_description |
Short line under the title |
tagline |
Accent line under the channel name (default: Bringing your videos home) |
download.format |
yt-dlp quality string |
download.write_subtitles |
Download subtitles and auto-captions when true |
download.subtitle_langs |
Subtitle languages, e.g. ["en", "es"] |
download.max_videos |
Default cap (0 = no limit); usually overridden by N= |
download.skip_existing |
Only fetch new videos on re-runs |
export.shorts_only |
When true, export only Short-form videos |
export.reencode |
Re-encode to H.264/AAC MP4 (requires ffmpeg) |
export.target_resolution |
Max height when re-encoding, e.g. 1080 |
export.video_bitrate / export.audio_bitrate |
Bitrates when re-encoding, e.g. 6M / 192k |
After changing channel_name, channel_description, or tagline, run make manifest (Mac) or npm run manifest (Windows) so data.js updates before you copy the folder to family.
| Variable | Example | Effect |
|---|---|---|
URL |
URL="https://www.youtube.com/@You/shorts" |
Channel to download |
N |
N=5 |
Download the 5 most recent videos |
MAX |
MAX=0 |
Download the full channel |
PORT |
PORT=9000 |
Preview server port (default 8098) |
ALL |
ALL=1 |
Export all videos, not just Shorts |
Mac: make download N=5 URL="..." · make serve PORT=9000 · make export N=10 ALL=1
Windows: node scripts/download.js --max 5 "URL" · set PORT=9000 && npm start · node scripts/export.js --limit 10 --all
| Variable | Default | Description |
|---|---|---|
PORT |
8098 |
Preview server port |
HOST |
127.0.0.1 |
Bind address |
NO_OPEN |
— | Set to 1 to skip auto-opening the browser on start |
| What | How |
|---|---|
| Channel title & description | channel_name, channel_description, tagline in config.json, then make manifest |
| Light / dark theme | Sun/moon button in the top bar (pigeon-cache-theme in the browser) |
| Accent color & layout | CSS variables in styles.css (--accent, --bg, etc.) |
| Logo | SVG in index.html and icon.svg |
| Path | Contents |
|---|---|
downloads/ |
Archived videos and metadata, one folder per video id |
downloads/archive.txt |
yt-dlp download ledger |
data.js |
Generated video index (window.PC_DATA) — run make manifest |
export/ |
Generated export copies with metadata sidecars |
downloads/, export/, and data.js are git-ignored because they can be very large.
| Goal | What to copy |
|---|---|
| Share with family | Entire pigeon-cache/ folder |
| Full project backup | Entire pigeon-cache/ folder |
| Videos only (no viewer) | export/ after make export, or raw downloads/ |
Short-form videos are detected when the video is portrait, the URL contains /shorts/, or duration is ≤ 60s (when dimensions are missing).
The viewer shows Shorts badges, a dedicated Shorts tab (when mixed with long-form), portrait players with loop/autoplay, and a “More Shorts” sidebar rail.
| Path | What it does |
|---|---|
server.js |
Local preview server with HTTP range support |
config.json |
Channel URL, branding, download and export settings |
scripts/download.js |
yt-dlp archiver |
scripts/build-manifest.js |
Scans downloads/ → data.js |
scripts/export.js |
Export with metadata sidecars |
index.html |
Viewer page — double-click for offline use |
styles.css |
Viewer styling |
app.js |
Viewer logic (vanilla JS) |
data.js |
Generated video index |
downloads/ |
Generated archived videos |
export/ |
Generated export copies |
Makefile |
Convenience targets (Mac) |
Need custom workflows, features, or integrations?
Contact us at:
MIT — see LICENSE.md.
Archive only your own channel or content you are authorized to share. Respect platform terms of service and creators' rights.