@unngh/youtube-cli
v1.2.0
Published
YouTube Data API CLI tool for Node.js — full parity with the Dart yt_cli: search, channels, videos, playlists, comments, comment-threads, subscriptions, broadcast, stream, analytics, members, thumbnails, watermarks, activities, and more.
Maintainers
Readme
@unngh/youtube-cli
YouTube Data API CLI tool for Node.js — search, channels, videos, playlists, activities, live streaming, comments, analytics, and more. Compiled from the yt Dart package via dart2js.
Features
- 🔍 Full YouTube Data API coverage — search, channels, videos, playlists, activities, comments, subscriptions, members
- 📡 Live Streaming API — manage broadcasts, streams, transitions, and bindings
- 📊 YouTube Analytics API — query metrics, manage analytics groups and group items
- 🔑 Auth flexibility — API key (read-only) or OAuth 2.0 (read/write)
- 📦 Single binary install — runs anywhere Node.js ≥ 18 runs (macOS, Linux, Windows)
- 🧱 JSON-first output — every command emits JSON to stdout, perfect for
jqpipelines
Table of Contents
Requirements
- Node.js ≥ 18 (the CLI ships as ESM and uses native
fetch) - A YouTube Data API key or OAuth 2.0 client credentials from Google Cloud Console
Installation
# Install globally
npm install -g @unngh/youtube-cli
# Or run directly with npx
npx @unngh/youtube-cliConfiguration
YouTube API access requires either an API key (read-only) or OAuth 2.0 credentials.
| Action Type | Authentication Requirement | Why | |---|---|---| | Reading Public Data | API Key or OAuth 2.0 | Accesses data anyone can see (e.g., public video titles, search results). | | Reading Private Data | OAuth 2.0 Required | Accesses data specific to a user (e.g., a user's private videos or watch history). | | Writing/Modifying Data | OAuth 2.0 Required | Performs actions on behalf of a user (e.g., uploading, deleting, or commenting). |
API Key
Provide your YouTube Data API key using any of:
- Flag:
--api-key YOUR_API_KEY - Environment variable:
export YT_API_KEY=YOUR_API_KEY .envfile in the current working directory (see .env File)
To obtain an API key, visit the Google Cloud Console and create a new API key with YouTube Data API v3 enabled.
OAuth 2.0
For write operations (uploads, comments, subscriptions, broadcast control) and private-data reads, use OAuth 2.0 credentials.
⚠️ The Node CLI does NOT run the OAuth web flow. The
authorizecommand in@unngh/youtube-clionly prints which environment variables to set. To generate the access-tokens file, use the Dart-native yt_cli (or any compatibleoauth2-format tooling) once, then point the Node CLI at the resulting files.
One-time token generation (via Dart yt_cli)
# Install once (Homebrew or pub.dev)
brew install cdavis-code/yt/yt # or: dart pub global activate yt_cli
# Run the interactive web flow — opens browser, writes access_tokens.json
yt authorize \
--credentials-file ~/.yt/client_secrets.json \
--tokens-file ~/.yt/access_tokens.jsonDownload client_secrets.json from the
Google Cloud Console
(Create credentials → OAuth client ID → Desktop app).
Point @unngh/youtube-cli at the generated files
| Variable | Required | Description |
|---|---|---|
| YT_CLIENT_SECRETS_FILE | Yes (OAuth) | Path to OAuth client secrets JSON downloaded from Google Cloud Console |
| YT_ACCESS_TOKENS_FILE | Yes (OAuth) | Path to the access tokens JSON written by yt authorize |
| YT_API_KEY | Optional | Used as fallback for read-only/public-data calls |
export YT_CLIENT_SECRETS_FILE=~/.yt/client_secrets.json
export YT_ACCESS_TOKENS_FILE=~/.yt/access_tokens.json
# Now write operations work, e.g. uploading a thumbnail
youtube-cli thumbnails set --video-id VIDEO_ID --file ./cover.jpg🔄 Token format note: v3.0.1 of the underlying
ytlibrary migrated fromgoogleapis_authto the cross-platformoauth2package. Tokens generated byyt_cli < 3.0.0are not compatible — re-authorize once and they will work for both the Dart and Node CLIs.
.env File
The underlying yt package automatically loads variables from a .env file
in the current working directory. This is the recommended way to keep
credentials out of your shell history and CI logs.
Create .env in your project root:
# API key (read-only / public data)
YT_API_KEY=AIzaSyABC...
# OAuth 2.0 (read-write / private data)
YT_CLIENT_SECRETS_FILE=./.yt/client_secrets.json
YT_ACCESS_TOKENS_FILE=./.yt/access_tokens.jsonThen add .env and .yt/ to your .gitignore. CLI flags (e.g. --api-key)
still take precedence over .env and shell environment values.
Commands
| Command | Subcommands | Description |
|---------|-------------|-------------|
| search | list | Search for videos, channels, and playlists |
| channels | list, update | Get / update channel information |
| videos | list, insert, update, delete, rate | Get / upload / modify / rate videos |
| playlists | list, insert, update, delete | Manage playlists |
| activities | list | Get channel activity feeds |
| broadcast | list, insert, update, delete, transition, bind | Manage live broadcasts |
| stream | list, insert, update, delete | Manage live streams |
| comments | list, list-by-ids, list-by-id, list-by-parent-id, insert, add, update, change, delete, set-moderation-status | Manage comments |
| comment-threads | list, list-by-video-id, list-by-channel-id, list-by-ids, list-by-id, insert, add | Manage comment threads |
| subscriptions | list, insert, delete | Manage subscriptions |
| thumbnails | set | Upload video thumbnails |
| watermarks | set, unset | Manage channel watermarks |
| members | list | List channel members |
| memberships-levels | list | List membership levels |
| video-categories | list | List video categories |
| video-abuse-report-reasons | list | List abuse report reasons |
| analytics | query, groups-list, groups-insert, groups-update, groups-delete, group-items-list, group-items-insert, group-items-delete | YouTube Analytics |
| authorize | — | OAuth authorization info |
| version | — | Display version |
Global Options
| Option | Description |
|--------|-------------|
| --api-key <key> | YouTube Data API key (overrides YT_API_KEY env var) |
| --log-level <level> | Log level: all, debug, info, warning, error (default: off) |
| --help | Show help for a command |
| --version | Show version number |
Examples
Search
# Search for videos
youtube-cli search list --q "TypeScript tutorial" --max-results 5
# Search for channels only
youtube-cli search list --q "Google" --type channelChannels
# Get channel by ID
youtube-cli channels list --id UC_x5XG1OV2P6uZZ5FSM9Ttw --part snippet,statistics
# Get channel by username
youtube-cli channels list --for-username GoogleDevelopersVideos
# Get video details
youtube-cli videos list --id dQw4w9WgXcQ --part snippet,statistics,contentDetails
# Get multiple videos
youtube-cli videos list --id "dQw4w9WgXcQ,jNQXAC9IVRw"
# Upload a new video (OAuth required)
youtube-cli videos insert \
--video-file ./clip.mp4 \
--body '{"snippet":{"title":"My upload","description":"Hello world"},"status":{"privacyStatus":"private"}}' \
--notify-subscribers false
# Update an existing video's metadata
youtube-cli videos update --body '{"id":"VIDEO_ID","snippet":{"title":"New title","categoryId":"22"}}' --part snippet
# Rate a video (like / dislike / none)
youtube-cli videos rate --id VIDEO_ID --rating like
# Delete a video
youtube-cli videos delete --id VIDEO_IDPlaylists
# Get playlists for a channel
youtube-cli playlists list --channel-id UC_x5XG1OV2P6uZZ5FSM9Ttw --part snippet
# Get playlist by ID
youtube-cli playlists list --id PLRqwX-V7Uu6ZiZxtDDRCi6uhfTH4FilpH
# Create a new playlist (OAuth required)
youtube-cli playlists insert --body '{"snippet":{"title":"My new playlist"},"status":{"privacyStatus":"private"}}'
# Update a playlist
youtube-cli playlists update --body '{"id":"PLAYLIST_ID","snippet":{"title":"Renamed"}}' --part snippet
# Delete a playlist
youtube-cli playlists delete --id PLAYLIST_IDChannels
# Update channel metadata (OAuth required)
youtube-cli channels update --body '{"id":"CHANNEL_ID","brandingSettings":{"channel":{"description":"New description"}}}' --part brandingSettingsActivities
# Get recent activity for a channel
youtube-cli activities list --channel-id UC_x5XG1OV2P6uZZ5FSM9Ttw --max-results 10Broadcast
# List upcoming broadcasts
youtube-cli broadcast list --broadcast-status upcoming
# Create a new broadcast
youtube-cli broadcast insert --body '{"snippet":{"title":"My Live Stream","scheduledStartTime":"2026-06-01T20:00:00Z"},"status":{"privacyStatus":"public"}}'
# Transition a broadcast to live
youtube-cli broadcast transition --id BROADCAST_ID --broadcast-status live
# Bind a broadcast to a stream
youtube-cli broadcast bind --id BROADCAST_ID --stream-id STREAM_IDComments
# List replies to a comment
youtube-cli comments list --parent-id COMMENT_ID
# Get a single comment by ID
youtube-cli comments list-by-id --id COMMENT_ID
# List replies under a parent comment
youtube-cli comments list-by-parent-id --parent-id COMMENT_ID --max-results 50
# Insert a new comment (raw body)
youtube-cli comments insert --body '{"snippet":{"parentId":"COMMENT_ID","textOriginal":"Great video!"}}'
# Reply to a comment (shorthand helper)
youtube-cli comments add --parent-id COMMENT_ID --text "Great video!"
# Modify an existing comment's text (shorthand helper)
youtube-cli comments change --id COMMENT_ID --text "Edited reply"
# Set moderation status
youtube-cli comments set-moderation-status --id COMMENT_ID --moderation-status publishedComment Threads
# List all top-level threads on a video
youtube-cli comment-threads list-by-video-id --video-id VIDEO_ID --max-results 25
# List all threads on a channel (across all videos)
youtube-cli comment-threads list-by-channel-id --channel-id CHANNEL_ID
# Look up specific threads by ID
youtube-cli comment-threads list-by-ids --ids THREAD_ID_1,THREAD_ID_2
# Post a new top-level comment on a video (shorthand helper)
youtube-cli comment-threads add --video-id VIDEO_ID --text "First!"Subscriptions
# List subscriptions for a channel
youtube-cli subscriptions list --channel-id UC_x5XG1OV2P6uZZ5FSM9Ttw
# List your own subscriptions (requires OAuth)
youtube-cli subscriptions list --mine
# Subscribe to a channel
youtube-cli subscriptions insert --body '{"snippet":{"resourceId":{"kind":"youtube#channel","channelId":"UC_x5XG1OV2P6uZZ5FSM9Ttw"}}}'
# Unsubscribe
youtube-cli subscriptions delete --id SUBSCRIPTION_IDAnalytics
# Query channel analytics for a date range
youtube-cli analytics query --ids "channel==MINE" --start-date 2026-01-01 --end-date 2026-01-31 --metrics views,likes,comments
# Query with dimensions and filters
youtube-cli analytics query --ids "channel==MINE" --start-date 2026-01-01 --end-date 2026-01-31 --metrics views --dimensions day --sort -views
# List analytics groups
youtube-cli analytics groups-list --mine
# Create an analytics group
youtube-cli analytics groups-insert --body '{"snippet":{"title":"Top Videos"}}'Output
All commands output JSON to stdout, making it easy to pipe into other tools:
youtube-cli search list --q "Dart" | jq '.items[].snippet.title'Build Process
The CLI is compiled from the yt_cli Dart package using dart2js, then wrapped with a TypeScript/Commander.js interface via tsup.
# Build from the yt_cli_js package directory
npm run buildRelated
- yt — Core Dart package for YouTube APIs
- yt_cli — Native Dart CLI (installable via Homebrew)
- @unngh/youtube-api — JavaScript/TypeScript library bindings
- CHANGELOG — Release history
- GitHub Repository
License
MIT License — see LICENSE for details.
