yt-local
A privacy-focused, browser-based YouTube client that routes requests through Tor for anonymous viewing—without compromising on speed or features.
Features • Install • Usage • Screenshots
Note
How it works: yt-local mirrors YouTube's web requests (using the same Invidious/InnerTube endpoints as yt-dlp and Invidious) but strips JavaScript and serves a lightweight HTML frontend. No API keys needed.
Overview
yt-local is a lightweight, self-hosted YouTube client written in Python that gives you:
- Privacy-first: All requests route through Tor by default (video optional), keeping you anonymous.
- Fast page loads: No lazy-loading, no layout reflows, instant comment rendering.
- Full control: Customize subtitles, related videos, comments, and playback speed.
- High quality: Supports all YouTube video qualities (144p–2160p) via DASH muxing.
- Zero ads: Clean interface, no tracking, no sponsored content.
- Self-hosted: You control the instance—no third-party trust required.
Features
| Category | Features |
|---|---|
| Core | Search, channels, playlists, watch pages, comments, subtitles (auto/manual) |
| Privacy | Optional Tor routing (including video), automatic circuit rotation on 429 errors |
| Local | Local playlists (durable against YouTube deletions), thumbnail caching |
| UI | 3 themes (Light/Gray/Dark), theater mode, custom font selection |
| Config | Fine-grained settings: subtitle mode, comment visibility, sponsorblock integration |
| Performance | No JavaScript required, instant page rendering, rate limiting with exponential backoff |
| Subscriptions | Import from YouTube Takeout (CSV/JSON), tag organization, mute channels |
Advanced Capabilities
- SponsorBlock integration — skip sponsored segments automatically
- Custom video speeds — 0.25x to 4x playback rate
- Video transcripts — accessible via transcript button
- Video quality muxing — combine separate video/audio streams for non-360p/720p resolutions
- Tor circuit rotation — automatic new identity on rate limiting (429)
- File downloading — download videos/audio (disabled by default, configurable)
Screenshots
| Light Theme | Gray Theme | Dark Theme |
|---|---|---|
![]() |
![]() |
![]() |
| Channel View | Playlist View |
|---|---|
![]() |
(similar structure) |
Install
Windows
- Download the latest release ZIP
- Extract to any folder
- Run
run.batto start
GNU/Linux / macOS
# 1. Clone or extract the release
git clone https://github.com/user234683/yt-local.git
cd yt-local
# 2. Create and activate virtual environment
python3 -m venv venv
source venv/bin/activate # or `venv\Scripts\activate` on Windows
# 3. Install dependencies
pip install -r requirements.txt
# 4. Run the server
python3 server.py
Tip
If
pipisn't installed, use your distro's package manager (e.g.,sudo apt install python3-pipon Debian/Ubuntu).
Portable Mode
To keep settings and data in the same directory as the app:
# Create an empty settings.txt in the project root
touch settings.txt
python3 server.py
# Data now stored in ./data/ instead of ~/.yt-local/
Usage
Basic Access
- Start the server:
python3 server.py
# Server runs on http://127.0.0.1:9010 (configurable in /settings)
- Access YouTube via proxy:
http://localhost:9010/https://www.youtube.com/watch?v=vBgulDeV2RU
All YouTube URLs must be prefixed with http://localhost:9010/https://.
-
(Optional) Use Redirector to auto-redirect YouTube URLs:
- Firefox: Redirector addon
- Chrome: Redirector addon
- Pattern:
^(https?://(?:[a-zA-Z0-9_-]*\.)?(?:youtube\.com|youtu\.be|youtube-nocookie\.com)/.*) - Redirect to:
http://localhost:9010/$1
Note
To use embeds on web pages, make sure "Iframes" is checked under advanced options in your redirector rule.
Tor Routing
Important
Recommended for privacy. In
/settings, set Route Tor to"On, except video"(or"On, including video"), then save.
Running Tor
Option A: Tor Browser (easiest)
- Launch Tor Browser and leave it running
- yt-local uses port
9150(Tor Browser default)
Option B: Standalone Tor
# Linux (Debian/Ubuntu)
sudo apt install tor
sudo systemctl enable --now tor
# Configure yt-local ports (if using default Tor ports):
# Tor port: 9150
# Tor control port: 9151
Warning
Video over Tor is bandwidth-intensive. Consider donating to Tor node operators to sustain the network.
Import Subscriptions
- Go to Google Takeout
- Deselect all → select only Subscriptions → create export
- Download and extract
subscriptions.csv(path:YouTube and YouTube Music/subscriptions/subscriptions.csv) - In yt-local: Subscriptions → Import → upload CSV
Important
The CSV file must contain columns:
channel_id,channel_name,channel_url
Supported formats
- Google Takeout CSV
- Google Takeout JSON (legacy)
- NewPipe JSON export
- OPML (from YouTube's old subscription manager)
Configuration
Visit http://localhost:9010/settings to configure:
| Setting | Description |
|---|---|
| Route Tor | Off / On (except video) / On (including video) |
| Default subtitles | Off / Manual only / Auto + Manual |
| Comments mode | Shown by default / Hidden by default / Never |
| Related videos | Same options as comments |
| Theme | Light / Gray / Dark |
| Font | Browser default / Serif / Sans-serif |
| Default resolution | Auto / 144p–2160p |
| SponsorBlock | Enable Sponsored segments skipping |
| Proxy images | Route thumbnails through yt-local (for privacy) |
Troubleshooting
| Issue | Solution |
|---|---|
| Port already in use | Change port_number in /settings or kill existing process: pkill -f "python3 server.py" |
| 429 Too Many Requests | Enable Tor routing for automatic IP rotation, or wait 5-10 minutes |
| Failed to connect to Tor | Verify Tor is running: tor --version or launch Tor Browser |
| Subscriptions not importing | Ensure CSV has columns: channel_id,channel_name,channel_url |
| Settings persist across runs | Check ~/.yt-local/settings.txt (non-portable) or ./settings.txt (portable) |
Development
Running Tests
source venv/bin/activate # if not already in venv
make test
Project Structure
yt-local/
├── youtube/ # Core application logic
│ ├── __init__.py # Flask app entry point
│ ├── util.py # HTTP utilities, Tor manager, fetch_url
│ ├── watch.py # Video/playlist page handlers
│ ├── channel.py # Channel page handlers
│ ├── playlist.py # Playlist handlers
│ ├── search.py # Search handlers
│ ├── comments.py # Comment extraction/rendering
│ ├── subscriptions.py # Subscription management + SQLite
│ ├── local_playlist.py # Local playlist CRUD
│ ├── proto.py # YouTube protobuf token generation
│ ├── yt_data_extract/ # Polymer JSON parsing abstractions
│ └── hls_cache.py # HLS audio/video streaming proxy
├── templates/ # Jinja2 HTML templates
├── static/ # CSS/JS assets
├── translations/ # i18n files (Babel)
├── tests/ # pytest test suite
├── server.py # WSGI entry point
├── settings.py # Settings parser + admin page
├── generate_release.py # Windows release builder
└── manage_translations.py # i18n maintenance script
Note
For detailed architecture guidance, see
docs/HACKING.md.
Contributing
Contributions welcome! Please:
- Read
docs/HACKING.mdfor coding guidelines - Follow PEP 8 style (use
ruff format) - Run tests before submitting:
pytest - Ensure no security issues:
bandit -r . - Update docs for new features
Security Notes
- No API keys required — uses same endpoints as public YouTube web interface
- Tor is optional — disable in
/settingsif you prefer performance over anonymity - Rate limiting handled — exponential backoff (max 5 retries) with automatic Tor circuit rotation
- Path traversal protected — user input validated against regex whitelists (CWE-22)
- Subprocess calls secure — build scripts use
subprocess.run([...])instead of shell (CWE-78)
Note
GPG key for release verification:
72CFB264DFC43F63E098F926E607CE7149F4D71C
Public Instances
yt-local is designed for self-hosting.
Donate
This project is 100% free and open-source. If you'd like to support development:
- Bitcoin:
1JrC3iqs3PP5Ge1m1vu7WE8LEf4S85eo7y - Tor node donation: https://torservers.net/donate
License
GNU Affero General Public License v3.0+
See LICENSE for full text.
Exception for youtube-dl
Permission is granted to relicense code portions into youtube-dl's license (currently GPL) for direct inclusion into the official youtube-dl repository. This exception does not apply to forks or other uses—those remain under AGPLv3.
Similar Projects
| Project | Type | Notes |
|---|---|---|
| invidious | Server | Multi-user instance, REST API |
| Yotter | Server | YouTube + Twitter integration |
| FreeTube | Desktop | Electron-based client |
| NewPipe | Mobile | Android-only, no JavaScript |
| mps-youtube | Terminal | CLI-based, text UI |
| youtube-local | Browser | Original project (base for yt-local) |
Made for privacy-conscious users
Last updated: 2026-04-19



