A comprehensive YouTube statistics platform featuring a Go-based HTTP API, professional CLI tool, and browser extension for real-time video stats.
- Professional command-line interface powered by Cobra + Viper
- Multiple commands:
serve,get,version - Configuration via files, environment variables, or flags
- Multiple output formats: table, JSON, YAML
- Beautiful formatted output with emojis and thousands separators
- 📊 Fetch YouTube video statistics (views, likes, comments, etc.)
- 📈 Prometheus metrics endpoint
- 🔭 OpenTelemetry tracing with stdout exporter
- 📝 Structured logging with zerolog
- 📄 OpenAPI 3.0 specification for API documentation
- 🐳 Docker support for easy deployment
- Comprehensive test suite with 42.3% coverage
- Unit + Integration tests
- Race detector enabled
- GitHub Actions CI/CD pipeline
- Security scanning (Gosec + CodeQL)
- Automated dependency updates
- Real-time stats overlay while watching YouTube videos
- Modern glassmorphism UI
- Auto-refresh with configurable intervals
- Customizable settings (API endpoint, refresh rate)
- CLI Tool: Multi-command interface with flexible configuration
- API Service: RESTful API for fetching YouTube statistics
- Chrome Extension: Browser extension for in-video stats overlay
- CI/CD Pipeline: Production-ready automated testing and deployment
- Go 1.24 or later
- YouTube Data API v3 key (Get one here)
- Docker and Docker Compose (optional, for containerized deployment)
- Clone the repository:
git clone https://github.com/ennc0d3/yt-stats.git
cd yt-stats- Create a
.envfile from the example:
cp .env.example .env- Edit
.envand add your YouTube API key:
YTSTATS_API_KEY=your_actual_api_key_here- Start the service:
docker-compose up -d- Test the API:
# Replace VIDEO_ID with an actual YouTube video ID
curl "http://localhost:8998/stats?video_id=dQw4w9WgXcQ"- Set your API key:
export YTSTATS_API_KEY=your_youtube_api_key- Build and run:
go build -o yt-stats ./cmd/yt-stats
./yt-stats serve # Start API serverThe CLI tool provides multiple commands for different use cases.
# Start server (default port 8998)
yt-stats serve
# Custom port
yt-stats serve --port 9000
# Custom log level
yt-stats serve --log-level debug
# Using config file
yt-stats serve --config ~/.yt-stats.yaml# Get stats with default table output
yt-stats get dQw4w9WgXcQ
# JSON output
yt-stats get dQw4w9WgXcQ --format json
# YAML output
yt-stats get dQw4w9WgXcQ --format yaml
# Custom fields
yt-stats get dQw4w9WgXcQ --fields views,likes
# All fields
yt-stats get dQw4w9WgXcQ --fields views,likes,comments,favoritesExample output (table format):
╔═══════════════════════════════════════════════════════════╗
║ YouTube Video Statistics ║
╠═══════════════════════════════════════════════════════════╣
║ Title: Rick Astley - Never Gonna Give You Up ║
╠═══════════════════════════════════════════════════════════╣
║ 👁️ Views: 1,234,567,890 ║
║ 👍 Likes: 12,345,678 ║
║ 💬 Comments: 123,456 ║
╚═══════════════════════════════════════════════════════════╝
The CLI supports multiple configuration methods (in order of precedence):
- Command-line flags (highest priority)
- Environment variables (YTSTATS_*)
- Configuration file (.yt-stats.yaml)
- Defaults (lowest priority)
Create a configuration file:
cp .yt-stats.yaml.example ~/.yt-stats.yaml
# Edit with your settingsExample .yt-stats.yaml:
apiKey: "your_youtube_api_key_here"
port: 8998
logLevel: "info"Environment variables:
export YTSTATS_API_KEY="your_key"
export YTSTATS_PORT=8998
export YTSTATS_LOG_LEVEL="debug"yt-stats version
# Output:
# yt-stats version 1.0.0
# commit: dev
# built: unknown# General help
yt-stats --help
# Command-specific help
yt-stats serve --help
yt-stats get --helpGET /stats?video_id={VIDEO_ID}
Returns JSON with video statistics including views, likes, comments, etc.
Example:
curl "http://localhost:8998/stats?video_id=dQw4w9WgXcQ"GET /metrics
Returns Prometheus-formatted metrics for monitoring.
The API is fully documented using OpenAPI 3.0 specification.
Location: openapi.yaml
Features:
- Complete endpoint documentation
- Request/response schemas
- Validation patterns
- Example requests and responses
- Ready for SDK generation
View the API docs:
# Online with Swagger Editor
# Visit: https://editor.swagger.io/
# Paste contents of openapi.yaml
# Generate client SDK
npm install -g @openapitools/openapi-generator-cli
openapi-generator-cli generate -i openapi.yaml -g python -o ./client
# Serve interactive docs locally
npx @stoplight/prism-cli mock openapi.yamlDocumented Endpoints:
GET /stats?video_id={VIDEO_ID}- Fetch video statisticsGET /metrics- Prometheus metrics
The project has a production-ready CI/CD pipeline with GitHub Actions.
Documentation: See PIPELINE.md for complete details.
Workflows:
-
CI/CD Workflow (
.github/workflows/ci.yml)- Lint (golangci-lint v6)
- Test (unit + integration with race detector)
- Build (binary artifacts)
- Security (Gosec scanner)
- Docker (BuildKit with caching)
-
Build Workflow (
.github/workflows/go.yml)- Production deployment
- Docker Hub publishing
- Codecov integration
-
Security Workflow (
.github/workflows/codeql.yml)- CodeQL analysis
- Weekly scans
- Go + JavaScript coverage
Pipeline Features:
- ✅ Parallel job execution
- ✅ Smart caching (Go modules, Docker layers)
- ✅ Security scanning (Gosec + CodeQL)
- ✅ 42.3% test coverage
- ✅ Race detector enabled
- ✅ Automated dependency updates
Status Badges:

The project includes a Chrome extension that displays real-time YouTube statistics as an overlay while you watch videos.
-
Start the API server (see Quick Start above)
-
Load the extension:
- Open Chrome and go to
chrome://extensions/ - Enable "Developer mode" (toggle in top right)
- Click "Load unpacked"
- Select the
chrome-extensiondirectory from this project
- Open Chrome and go to
-
Configure settings:
- Click the extension icon in Chrome toolbar
- Set API endpoint (default:
http://localhost:8998) - Set refresh rate (default: 30 seconds)
- Click "Save Settings"
-
Watch YouTube videos - The stats overlay will automatically appear!
- 👁️ Real-time view count
- 👍 Real-time like count
- 💬 Real-time comment count
- 🔄 Auto-refresh with configurable intervals
- 🎨 Modern glassmorphism UI
- ⏸️ Collapsible/closeable overlay
- ⚙️ Customizable settings
For detailed documentation, see chrome-extension/README.md
Start the server:
# Using Docker Compose
docker-compose up -d
# OR using Go directly
export YTSTATS_API_KEY=your_youtube_api_key
go run cmd/yt-stats/main.goTest with curl:
# Test with a well-known video (Rick Astley - Never Gonna Give You Up)
curl "http://localhost:8998/stats?video_id=dQw4w9WgXcQ"
# Expected response (example):
# {
# "viewCount": "1234567890",
# "likeCount": "12345678",
# "commentCount": "123456",
# "favoriteCount": "0"
# }Test the metrics endpoint:
curl http://localhost:8998/metricsMissing video_id parameter:
curl "http://localhost:8998/stats"
# Expected: 400 Bad Request - "video_id parameter is missing"Invalid video_id:
curl "http://localhost:8998/stats?video_id=invalid"
# Expected: 500 Internal Server Error - "failed to retrieve video statistics"Valid video_id:
# Use any real YouTube video ID from youtube.com/watch?v=VIDEO_ID
curl "http://localhost:8998/stats?video_id=YOUR_VIDEO_ID"
# Expected: 200 OK with JSON statsLoad the extension:
- Open Chrome:
chrome://extensions/ - Enable "Developer mode"
- Click "Load unpacked"
- Select
chrome-extension/folder - ✅ Extension should appear with "YouTube Stats Overlay" title
Configure settings:
- Click extension icon in toolbar
- Verify default settings:
- ✅ "Enable Stats Overlay" is checked
- ✅ API Endpoint shows
http://localhost:8998 - ✅ Refresh Rate shows
30seconds
- Click "Save Settings"
- ✅ You should see "Settings saved!" message
Navigate to any YouTube video:
https://www.youtube.com/watch?v=dQw4w9WgXcQ
Verify overlay appears:
- ✅ Stats overlay appears in top-right corner
- ✅ Shows "📊 Video Stats" header
- ✅ Shows three stats: 👁️ Views, 👍 Likes, 💬 Comments
- ✅ Numbers are formatted with thousands separators (e.g., "1,234,567")
- ✅ Shows "Last updated" timestamp at bottom
Test overlay controls:
- ✅ Click − button → Panel collapses (only header visible)
- ✅ Click + button → Panel expands again
- ✅ Click × button → Overlay disappears
Test video navigation:
- ✅ Click another video in sidebar
- ✅ Overlay should update with new video's stats
- ✅ Stats should refresh automatically (wait 30 seconds)
Stop the API server:
docker-compose down
# OR press Ctrl+C if running with GoReload YouTube page:
- ✅ Overlay should show error message:
- "
⚠️ Error loading stats" - Shows connection error
- Shows helpful hint about API server
- "
Restart API server:
docker-compose up -dReload YouTube page:
- ✅ Overlay should work again with stats
Open extension popup:
- Change refresh rate to
10seconds - Click "Save Settings"
- ✅ Settings saved message appears
Reload YouTube page:
- ✅ Stats should now refresh every 10 seconds
- ✅ Check "Last updated" timestamp changes
Disable overlay:
- Open extension popup
- Uncheck "Enable Stats Overlay"
- Click "Save Settings"
- Reload YouTube page
- ✅ Overlay should NOT appear
# Run all unit tests
go test -v -short ./...
# OR using Make
make test-unit
# Expected output:
# === RUN TestHandleVideoInfo_MissingVideoID
# --- PASS: TestHandleVideoInfo_MissingVideoID (0.00s)
# === RUN TestHandleVideoInfo_EmptyVideoID
# --- PASS: TestHandleVideoInfo_EmptyVideoID (0.00s)
# ...
# PASS
# ok github.com/ennc0d3/yt-stats/internal/api# Set your YouTube API key
export YTSTATS_API_KEY=your_actual_api_key
# Run integration tests
go test -v -tags=integration ./...
# OR using test script
./test.sh
# Expected output:
# === RUN TestIntegration_VideoStats
# --- PASS: TestIntegration_VideoStats (1.50s)
# integration_test.go:XX: Video stats: Views=1234567890, Likes=12345678, Comments=123456
# PASS# Run all tests with coverage report
./test.sh
# OR using Make
make test
# Expected output:
# Running yt-stats tests...
#
# === Running Unit Tests ===
# ...tests pass...
#
# === Running Integration Tests ===
# ...tests pass...
#
# === Generating Coverage Report ===
# github.com/ennc0d3/yt-stats/internal/api/handler.go:13: handleVideoInfo 57.1%
# github.com/ennc0d3/yt-stats/internal/api/server.go:18: SetupRoutes 100.0%
# ...
# total: 42.3%
#
# ✅ All tests passed!# Detect race conditions
go test -race ./...
# Expected: No race conditions detected# Test Docker build
make docker-build
# OR
docker build -t yt-stats:test .
# Expected: Build completes successfully
# ✅ Successfully tagged yt-stats:test1. Start everything:
# Terminal 1: Start API
export YTSTATS_API_KEY=your_key
docker-compose up2. Test API:
# Terminal 2: Test API
curl "http://localhost:8998/stats?video_id=dQw4w9WgXcQ" | jq
# ✅ Should return formatted JSON with stats3. Test Chrome Extension:
- Load extension in Chrome
- Navigate to
https://www.youtube.com/watch?v=dQw4w9WgXcQ - ✅ Overlay should show matching stats from step 2
4. Verify auto-refresh:
- Wait 30 seconds (or your configured refresh rate)
- ✅ "Last updated" timestamp should change
- ✅ Stats might update if video stats changed
Check API key:
echo $YTSTATS_API_KEY
# Should show your API key, not emptyCheck server is running:
curl http://localhost:8998/metrics
# Should return Prometheus metricsCheck logs:
# Docker logs
docker-compose logs -f
# OR if running with Go, check terminal outputOpen Chrome DevTools:
- On YouTube page, press F12
- Check Console tab for errors
- Look for "YouTube Stats Overlay - Content script loaded"
Check extension background service worker:
- Go to
chrome://extensions/ - Find "YouTube Stats Overlay"
- Click "service worker" link
- Check for error messages
Verify API is accessible:
# From browser console (F12), run:
fetch('http://localhost:8998/stats?video_id=dQw4w9WgXcQ')
.then(r => r.json())
.then(console.log)Run only unit tests (faster):
make test-unit
# Skips integration tests that make real API callsIncrease test timeout:
go test -timeout 5m ./...# Using Go
go build -v ./cmd/yt-stats
# Using Make
make build# Run all tests with coverage
./test.sh
# Or using Make
make test # All tests with coverage
make test-unit # Unit tests only
make test-integration # Integration tests (requires YTSTATS_API_KEY)Test Coverage: 42.3% on API package with comprehensive unit and integration tests
# Using Docker directly
docker build -t yt-stats .
# Using Make
make docker-build
# Using Docker Compose
make docker-upThe application is configured via environment variables:
YTSTATS_API_KEY(required): Your YouTube Data API v3 key
- Port: 8998
- Logging: Structured JSON logging via zerolog
- Tracing: OpenTelemetry with stdout exporter
- Metrics: Prometheus metrics exposed on
/metrics - Router: Gorilla Mux with OpenTelemetry middleware
.
├── cmd/yt-stats/ # Application entry point
│ ├── main.go # Main CLI entry
│ └── cmd/ # CLI commands (NEW!)
│ ├── root.go # Root command with viper config
│ ├── serve.go # API server command
│ ├── get.go # Stats fetcher command
│ └── version.go # Version command
├── internal/api/ # API handlers and server logic
│ ├── server.go # HTTP server setup
│ ├── handler.go # Request handlers
│ ├── ytutil.go # YouTube API integration
│ ├── handler_test.go # Handler unit tests
│ ├── server_test.go # Server route tests
│ └── integration_test.go # Integration tests
├── chrome-extension/ # Chrome browser extension
│ ├── manifest.json # Extension configuration (Manifest V3)
│ ├── js/ # JavaScript files
│ │ ├── content.js # YouTube page overlay injector
│ │ ├── background.js # Service worker
│ │ └── popup.js # Settings UI logic
│ ├── css/ # Styling
│ │ └── overlay.css # Stats overlay styles (glassmorphism)
│ ├── popup.html # Settings page
│ └── README.md # Extension documentation
├── .github/workflows/ # GitHub Actions CI/CD
│ ├── ci.yml # Comprehensive CI pipeline (NEW!)
│ ├── go.yml # Build and deployment
│ └── codeql.yml # Security scanning
├── openapi.yaml # OpenAPI 3.0 specification (NEW!)
├── PIPELINE.md # CI/CD documentation (NEW!)
├── .yt-stats.yaml.example # Config file example (NEW!)
├── Dockerfile # Multi-stage Docker build
├── docker-compose.yml # Docker Compose setup
├── Makefile # Development tasks
├── test.sh # Test runner script
└── README.md # This file
# CLI Tool
yt-stats serve # Start API server
yt-stats get VIDEO_ID # Get stats (table)
yt-stats get VIDEO_ID -f json # Get stats (JSON)
yt-stats version # Show version
# API Server
curl "http://localhost:8998/stats?video_id=VIDEO_ID"
curl http://localhost:8998/metrics
# Development
make build # Build binary
make test # Run all tests with coverage
make test-unit # Run unit tests only
make docker-build # Build Docker image
# Docker
docker-compose up -d # Start services
docker-compose logs -f # View logs
docker-compose down # Stop services- Command-line flags (--api-key, --port)
- Environment variables (YTSTATS_API_KEY, YTSTATS_PORT)
- Config file (~/.yt-stats.yaml)
- Defaults
- OpenAPI Spec: openapi.yaml
- Pipeline Docs: PIPELINE.md
- Chrome Extension: chrome-extension/README.md
- GitHub Repository: https://github.com/ennc0d3-dev/ytstats
See LICENSE file for details.