- JavaScript 78%
- CSS 13.1%
- HTML 8.6%
- Shell 0.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| docs/superpowers | ||
| icons | ||
| scripts | ||
| server-sync-api | ||
| test | ||
| website | ||
| .gitignore | ||
| background.js | ||
| block.css | ||
| changelog-data.js | ||
| changelog.css | ||
| changelog.html | ||
| changelog.js | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| content-main.js | ||
| content.js | ||
| dashboard.css | ||
| dashboard.html | ||
| dashboard.js | ||
| defaults.js | ||
| help.css | ||
| help.html | ||
| help.js | ||
| i18n-content.js | ||
| i18n.js | ||
| LICENSE | ||
| livechat.js | ||
| manifest.json | ||
| package-lock.json | ||
| package.json | ||
| popup.css | ||
| popup.html | ||
| popup.js | ||
| README.MD | ||
| rules.json | ||
| settings.css | ||
| settings.html | ||
| settings.js | ||
CleanWatch
CleanWatch is a Chromium extension for people who want YouTube to be useful without constantly trying to pull them into more watching. The goal is simple: make YouTube better for intentional viewing by removing the parts that are designed to distract, tempt, or keep you scrolling.
Chrome Web Store · Website · Wiki · Issues
What it provides
- Distraction reduction and interruption cleanup for YouTube pages.
- Removal of Shorts shelves, Shorts links, and optional redirection from the Shorts player to the normal video player.
- Removal of algorithmic recommendations such as related videos, homepage suggestions, autoplay-driven browsing, and sponsored content.
- Feed filtering by minimum view count threshold and members-first content, with a per-channel allowlist for members-first channels you want to keep.
- A cleaner interface with optional controls for comments, live chat, notification badges, thumbnail previews, sidebar links, and promotional buttons like Thanks, Clip, and Join.
- Focus controls such as daily watch-time limits, break reminders, and scheduled on/off hours.
- Playback preferences including forced theater mode, preferred audio language, preferred playback quality, and optional auto-like on watch pages after a configurable watched-percentage threshold with a configurable in-player confirmation toast.
- Keyword blocking with a right-click context menu for adding keywords directly from YouTube pages, dashboard management, and optional encrypted sync across devices.
- A compact popup for quick actions, plus dedicated settings and dashboard pages for full configuration, watch-time history, top channels, auto-liked video count, keyword blocklist, members-first allowlist, and privacy information.
- Playback resilience: a video server that stops responding is dropped early so the player fails over to its backup immediately, instead of waiting out YouTube's own multi-second timeout on every chunk.
- Filter health checks that run in the background and notice when a YouTube markup change has silently stopped one of CleanWatch's page rules from matching, with a heads-up in the popup and a copyable report on the dashboard.
- Localized UI in English, Dutch, German, and French.
Every setting, with its default and what it does, is in the Settings reference.
What this project is not trying to do
- It is not trying to replace YouTube with a separate frontend or alternative player.
- It is not trying to automate subscriptions, downloads, scraping, channel management, or account activity.
- It is not trying to collect user analytics, telemetry, or behavioral data for external reporting.
- It is not trying to promise perfect long-term compatibility with every YouTube UI change. YouTube changes its markup often, so this extension will always need maintenance — since v1.21.0 it at least says so instead of failing silently.
- It is not trying to require a dedicated backend in order to function. The extension still works fully locally when server sync is not configured.
Install
From the Chrome Web Store for automatic updates, or manually in any Chromium browser: download cleanwatch-latest.zip from the website, unzip it, then use Load unpacked in chrome://extensions with Developer mode on.
The website download, the release attachment, and the Web Store upload are the same bytes from the same build.
Documentation
| Settings reference | Every setting, its default, and what it does. Generated from the source each release. |
| Troubleshooting | A filter stopped working, videos start slowly, sync problems. |
| Architecture | How the pieces fit — read this before changing code. |
| CHANGELOG.md | The full technical record. changelog-data.js holds the shorter user-facing version. |
| Privacy policy | What is stored, where, and why. |
The extension also ships its own Help page, which is the same settings reference translated into all four languages.
Development
There is no build step. The files in this repository are the files that ship, so you can clone it and load the folder directly with Load unpacked.
npm install # jsdom, for the tests — nothing the extension itself needs
npm test # node --test test/*.test.js
The suite is plain node --test, no framework, and runs in a few seconds. test/page-load.test.js is the one worth knowing about: it loads every extension page exactly as the browser does and fails on any uncaught error, because v1.17.0 and v1.18.0 shipped a settings page that was dead on arrival and node --check passed it happily.
Two files are generated — do not edit them by hand:
| File | Regenerate with |
|---|---|
i18n-content.js |
node scripts/build-i18n-content.js |
| The wiki's Settings reference | node scripts/build-wiki-settings.js <wiki-clone>/Settings-Reference.md |
Where things go. Pure decision logic belongs in defaults.js as an FY_* export, with a test; the DOM or network code that acts on it belongs in the content scripts. Selectors that depend on YouTube's private markup go in the FY_AUDITED_SELECTORS registry so the audit can watch them.
Branches. Cut feature branches from dev and merge back with --no-ff. main is only reached through a PR from dev. Release markers are tags, not branches. CLAUDE.md has the full release routine.
Privacy
Local-first by default: settings, watch time, blocklists, stats, and the filter-health record all live in chrome.storage.local. No telemetry, no analytics, no account, and no external requests during normal browsing.
Server sync is optional and off by default. When enabled, settings and per-device stats are encrypted with AES-256-GCM on your device before anything is sent — the key is derived from your sync code and never leaves it. The server stores ciphertext it cannot read, plus a salted hash of your IP for abuse prevention. It is open source under server-sync-api/ and self-hostable.
Full details in the privacy policy.
Keyboard shortcuts
| Shortcut | Action |
|---|---|
| Alt+C | Toggle cinema/theater mode |
| Alt+R | Toggle related videos |
Reassign them at chrome://extensions/shortcuts.
License
CleanWatch is free software, licensed under the GNU General Public License, version 3 (GPL-3.0). You are free to use, study, modify, and redistribute the code. Any redistributed version — modified or not — must be made available under the same license with its source code.
See the LICENSE file for the full text, or read the plain-English summary at https://www.gnu.org/licenses/quick-guide-gplv3.html.
The CleanWatch source is hosted on our Forgejo instance at https://git.365devnet.eu/365DevNet/CleanWatch.
SponsorBlock
CleanWatch can skip in-video segments using data from the SponsorBlock community database (https://sponsor.ajay.app). This data is used under the Creative Commons BY-NC-SA 4.0 license, with attribution to SponsorBlock and its contributors.
Lookups are privacy-preserving: CleanWatch never sends the full video ID to the SponsorBlock server. It sends only the first four characters of the SHA-256 hash of the video ID (k-anonymity) and filters results locally.
Note: the SponsorBlock database license is non-commercial. This integration is intended for the free CleanWatch extension; monetizing CleanWatch while using SponsorBlock data would violate that license.