Download · Chrome Extension · Firefox Extension · Translate it
Focuser is a free, open-source website and application blocker built in Rust. Think Cold Turkey Blocker, but without the price tag and with the source code right here for you to judge.
It sits quietly in your system tray, blocks the sites you told it to block, and kills the apps you told it to kill. No cloud. No accounts. No telemetry. Just you vs. your distractions, and for once, you win.
It speaks ten languages: English, Español, Français, Deutsch, Português, Italiano, Русский, 中文, 日本語 and 한국어.
Dashboard - What is blocked right now, and a Pomodoro timer to start a session
Four counters across the top, then the focus session: three dials for focus, short break and long break, how many cycles before the long one, and a bar showing what the whole session adds up to. Block lists can be flipped on and off without leaving the page.
Block Lists - Group sites and apps, then schedule and lock each group on its own
A list is the unit everything else hangs off. Each one has its own websites, applications, schedule and exceptions, and can be locked so you cannot casually undo it.
Websites - Domains, keywords, wildcards, URL paths, or the whole internet
Pick the kind of rule and the hint underneath tells you what it will actually match. Starter lists sit right next to the add box: choose a category, hit Import, and the sites that are already there are skipped rather than duplicated.
Applications - Block programs by executable, full path, or window title
Blocked programs show their real icon, read out of the executable on your own machine. Nothing is fetched from the internet to do it.
Schedule - Always on, or painted onto a weekly grid
Leave a list always active, or switch to the grid and drag to paint the hours you want it blocking. Presets cover work hours, evenings and weekends. The summary underneath adds up your week and warns you when there are unsaved changes.
Allowances - A daily budget instead of an outright block
Give a site or app a number of minutes per day. When the budget runs out it is blocked for the rest of the day. Time can be counted only while the tab or window is actually focused, so a forgotten background tab does not drain it.
Statistics - What you tried to open, and how often you got stopped
Three views of the same data. Bars is attempts per day. Individual follows one site over time with its own share of the total. Detailed puts every site in one chart. Each site keeps the same colour every time, derived from a hash of its name.
Settings - Startup, browsers, extension status, and your data
Shows which browsers have the extension connected and offers to install it where they do not. Export every block list to a file or replace them from one, choose how long statistics are kept, and delete everything if you want to start over.
Block page - Names the site, says which rule caught it, and counts how many times you have tried today
The block happens before the page is drawn, so you never catch a glimpse of what you were avoiding. The message changes as the count climbs — the first visit of the day reads differently from the fourteenth.
Keyword rules say which word matched, not just that something did.
Toolbar popup - Block the site you are on, or take it out of every list at once
Shows which of your lists a site is actually in, rather than guessing one. Unblocking removes it from all of them. If the desktop app is closed the icon carries a red mark and the popup says so plainly, instead of pretending to work.
Welcome page - What to set up, and what changed in this version
Shown once on install and again after an update. Explains the one thing that needs setting up, which is keeping the desktop app running, and lays out the four kinds of rule side by side.
- Block websites - Add domains, keywords, wildcards, or URL paths. Or just block the entire internet and whitelist only what you need. Your call. Keywords, wildcards and URL paths are enforced by the browser extension, since a hosts file has no way to express a pattern. Focuser tells you on the Websites page when you have one of those rules and no extension installed.
- Block applications - Steam launching itself at 2pm on a Tuesday? Not anymore. Block by executable name, path, or window title.
- Real application icons - Blocked programs show their actual icon, read out of the executable on your own machine. Nothing is fetched from the internet to do it, because asking an icon service once per entry would hand over your entire block list.
- Pre-made block lists - 1,207 domains across 13 categories (social media, games, gambling, news, adult, etc.) ready to import with one click. We did the research so you don't have to.
- Bulk import - Drop a text file with 500 domains and they're all blocked in under a second. Also supports JSON.
- Exceptions (whitelist) - Block all of reddit.com but keep r/programming? Add exceptions for specific domains that bypass your block rules.
- Keyword blocking - Block any URL containing "game" or "shorts" or whatever your specific weakness is. We don't judge.
- Focus Lock - Lock a block list for a set duration. Once locked, you can't disable it, delete it, or edit it until the timer runs out. For when you genuinely don't trust yourself.
- Pomodoro focus sessions - Work for 25 minutes, break for 5, repeat — blocks toggle on and off automatically with each phase. After 4 work cycles you earn a longer break. Pick a preset (Classic, Long, Sprint) or set your own rhythm. The dashboard shows a live ring counting down with pause / skip / stop controls.
- Daily allowance quotas - Cap a site at N minutes per day. YouTube = 30 min/day. Reddit = 15. Whatever. The site stays accessible until you've burned through your quota, then it's blocked until midnight. Strict mode counts only the focused tab; loose mode counts any open tab.
- Smart focus interaction - Pomodoro and allowances are aware of each other. During a work phase, allowance back doors close — no sneaking off to YouTube even if you have minutes left. Hit pause and your allowances kick back in. Resume and they suspend again.
- Weekly schedule - Paint the hours a list is active on a 7×24 grid, or click a day or hour heading to fill a whole row or column. Block social media during work hours, allow it evenings and weekends. Or go 24/7 and be done with it.
- Browser extension - Available on Chrome Web Store and Firefox Add-ons. Also works on Edge, Brave, and Opera. Shows a clean "Site Blocked" page instead of a connection error.
- Browser enforcement - If a browser is running without the extension installed, Focuser will close it and show you an install prompt with a direct link to the store page. No more loopholes.
- Instant enforcement - Block a site in the app, it's blocked in your browser within 2 seconds. Unblock it, same deal. No restart required.
- Statistics - See what you tried to access, how many times it was blocked, and track it across days. The numbers are sometimes humbling.
- Runs elevated on Windows without a UAC prompt - The installer registers a logon task with highest privileges, so the copy that starts with your computer can write the hosts file. Launched by hand from the Start menu it runs unelevated, and the Dashboard says so rather than failing quietly.
- System tray - Runs in the background after you close the window. Double-click the tray icon to bring it back. Closing the app doesn't stop the blocking.
- Import/Export - Export your entire config (block lists, rules, schedules, exceptions) to a file. Import it on another machine. Move between computers without starting over.
- Ten languages - English, Spanish, French, German, Portuguese, Italian, Russian, Chinese, Japanese and Korean, across the whole app and the whole extension — window, tray menu, block page, popup and welcome page. The app follows a setting; the extension follows your browser, because
browser.i18nhas no way to change locale while running. Plurals go throughIntl.PluralRules, so Russian gets one/few/many and Japanese gets the single form it actually uses.
Focuser doesn't phone home. No analytics, no crash reporting, no usage tracking, no accounts, no cloud sync. Your block lists and stats live in a SQLite file on your machine and nowhere else.
That principle has teeth in places you might not expect. Application icons are read from the executables already on your disk rather than pulled from an icon service, because a request per entry would tell that service exactly what you are trying to avoid. See PRIVACY.md for the full policy.
- Rust (edition 2024) - Core engine, database, blocking logic, process management
- Tauri v2 - Desktop app framework (tiny bundle, native performance)
- SQLite - Local database via rusqlite
- React 19 + TypeScript + Tailwind CSS 4 - Frontend, built with Vite
- WXT + React + TypeScript - Browser extension (Manifest V3) for Chrome, Firefox, Edge, Brave, Opera
| Platform | Status |
|---|---|
| Windows 10/11 | Tested and working |
| macOS | Builds and passes CI, needs real-world testing |
| Linux | Builds and passes CI, needs real-world testing |
The core architecture is cross-platform and the test suite runs on all three in CI. Windows is the primary development target, so macOS and Linux are structurally there (hosts file blocking, process management, icon extraction) but haven't been put through their paces by an actual human. If you're on either, we'd love your help.
Every action the app can perform is one variant of a single Command enum, run by a single execute() in focuser-app. The desktop app, the CLI, the background service and the dev server are all thin shims over it — none of them holds logic of its own.
This isn't architecture for its own sake. Before it existed, the GUI and the service had quietly drifted into disagreeing about what "stop a block list" meant, and each grew its own bugs. Now there is one answer and four ways to ask for it.
The TypeScript types the frontend uses are generated from the Rust types by tauri-specta. Change a Rust struct and the frontend stops compiling until it's updated; CI fails if the checked-in bindings drift.
Focuser/
├── crates/
│ ├── focuser-common/ # Shared types, errors, process control, icon extraction
│ ├── focuser-core/ # Database, rules engine, blocking logic
│ ├── focuser-app/ # Command core — every action the app can perform
│ ├── focuser-native/ # Native messaging host (extension bridge)
│ ├── focuser-cli/ # Command-line interface
│ ├── focuser-devserver/ # Dev-only HTTP bridge, for running the UI in a browser
│ └── focuser-ui/ # Tauri desktop app
│ ├── src/ # Rust shell (blocker, extension API, native shims)
│ └── frontend/ # React + TypeScript + Tailwind
├── extension/ # Browser extension (WXT + React + TypeScript, MV3)
└── assets/ # Icons, branding, screenshots
- Hosts file - Blocked domains get redirected to
127.0.0.1in your system hosts file. This works at the OS level, before any browser even sees the request. - Process monitoring - A background thread scans running processes and terminates any that match your app blocking rules.
- Browser extension - Catches navigation to blocked URLs and replaces the page with a block screen. Handles keyword, wildcard, and URL-path rules the hosts file can't.
- Browser enforcement - Detects browsers running without the Focuser extension. After a grace period, it closes the browser and prompts you to install it.
- Local API - The app runs an HTTP API on
127.0.0.1:17549that the extension polls for rule updates. Everything stays local. - Pomodoro + allowance overlay - Pomodoro toggles a block list at each work/break boundary. Allowances track per-domain time from tab activity reported by the extension, and inject themselves as exceptions until the daily quota runs out — at which point the domain flips back into the blocked set until midnight.
One rule worth knowing: youtube.com, www.youtube.com and m.youtube.com are the same site everywhere in Focuser. Hostnames are canonicalised in exactly one place (focuser_common::host) and every rule, exception and allowance goes through it, so a block or an allowance can't apply to one form and miss another.
Grab the latest installer from the Releases page. Run it, install the browser extension when prompted, and you're good to go.
Prerequisites: Rust 1.85+ (edition 2024) and Node.js 20+ for the frontend.
git clone https://github.com/aadeshrao123/Focuser.git
cd Focuser
cargo build --workspace
cargo test --workspace
# Desktop app (requests admin rights on Windows)
cargo run -p focuser-uiBuilding installers additionally needs the sidecar binaries in place:
cargo build --release -p focuser-cli -p focuser-native
# copy each into crates/focuser-ui/binaries/<name>-<target-triple>[.exe]
cd crates/focuser-ui && npx --yes @tauri-apps/cli@2 buildnpx rather than cargo install tauri-cli: the CLI ships as a prebuilt binary on npm, so
this is a few seconds instead of the several minutes it takes to compile. cargo tauri build works too if you already have it installed.
The frontend can run in an ordinary browser against the real Rust command core, which makes it reachable by normal web tooling instead of only by clicking around a desktop window:
cargo run -p focuser-devserver -- --memory # HTTP bridge on :17550
cd crates/focuser-ui/frontend && npm run dev # Vite on :1420Both paths end in the same execute(), so what you exercise in the browser is the actual backend, not a mock that quietly drifts from it.
npm run typecheck # tsc
npm run lint # biome
npm test # vitest
npm run bindings # regenerate the TypeScript types from RustInstall from the store (recommended):
- Chrome / Edge / Brave / Opera: Chrome Web Store
- Firefox: Firefox Add-ons
Or build and load it yourself:
cd extension
npm install
npm run build # produces extension/.output/chrome-mv3/
npm run build:firefox # produces extension/.output/firefox-mv3/
npm test
npm run dev # live-reloading browser with the extension loaded
npm run preview # block page, popup and welcome page in an ordinary
# tab, with a picker for all ten languages- Chrome:
chrome://extensions→ Developer mode → Load unpacked →extension/.output/chrome-mv3/ - Firefox:
about:debugging→ This Firefox → Load Temporary Add-on →extension/.output/firefox-mv3/manifest.json(session-only; permanent installation needs AMO signing)
Disable the store version first — same extension ID, and you'd be testing old code.
We need your help. Seriously.
This project was built by a small team and there's a mountain of features we want to add. Whether you're a Rust wizard, a CSS artist, or someone who just found a bug while trying to block YouTube, your contributions matter.
See CONTRIBUTING.md for the full guide, but the short version:
- Fork the repo
- Create a branch (
git checkout -b feature/my-cool-thing) - Make your changes
- Run the checks below — CI runs the same ones on Windows, macOS and Linux
- Open a PR with a clear description
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
cd extension && npm test
cd crates/focuser-ui/frontend && npm run typecheck && npm run lint && npm test- macOS/Linux testing - We develop on Windows. The suite passes in CI on all three, but CI isn't a person using the thing. If it's broken on your OS, tell us.
- Application icons on macOS and Linux - The code is there and grounded in the published specs, but macOS apps that ship their icon only inside a compiled asset catalog aren't covered yet.
- Browser extension improvements - Better block page, usage tracking, Firefox quirks
- UI polish - If you have design skills and opinions, we want both
- Anti-circumvention - Making it harder to bypass blocks (for people who want that)
- Translations - Ten languages ship, and every one but English is a first draft written without a native speaker checking it. Fixing an awkward sentence in a language we already have is more useful than adding an eleventh. See TRANSLATING.md; it is one file and no Rust.
Open an issue with:
- What you expected to happen
- What actually happened
- Your OS and browser version
- Steps to reproduce
We'll get to it. Probably faster than you expect.
MIT License. See LICENSE for details.
Do whatever you want with this code. Fork it, modify it, sell it, use it to block your ex's social media during weak moments at 2am. We don't care. Just don't blame us if it works too well and you become unreasonably productive.
- Inspired by Cold Turkey Blocker, the gold standard we're chasing
- Built with Tauri, rusqlite, and too much caffeine
- Pre-made block lists curated from various open-source sources
If Focuser helped you get something done instead of scrolling Twitter for the 47th time today, consider starring the repo. It's free and it makes us unreasonably happy.
