Create Plyr instance immediately in start() so the styled player UI appears right away. Quality and audio controls are injected once the HLS manifest is ready, running doAdd() directly when player.ready is already true instead of waiting on the 'ready' event that already fired.
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://git.fridu.us/heckyel/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