A small macOS CLI to safely manage blocked domains in your hosts file.
It creates a dedicated managed section, normalizes domains/URLs for you, and creates timestamped backups before every write. It also supports temporary timed blocks.
Yes, this is a solid public utility project. It solves a real pain point: safe, repeatable hosts-file management with backup/restore and interactive remove mode.
- No API keys, tokens, or passwords are in the code.
- The app does not send data over the network.
- Do not publish personal backup files from
backups/*.bak(ignored by default).
Homebrew:
brew tap ai-armageddon/manage-hosts-cli
brew install manage-hosts-cli
blocked-sites --helpIf Homebrew cannot resolve the short formula name:
brew install ai-armageddon/manage-hosts-cli/manage-hosts-cliVerify which blocked-sites binary is active:
which -a blocked-sites
type -a blocked-sitesIf you previously created a manual symlink in /usr/local/bin, you may see
both Homebrew and manual paths. This is fine, but you can remove the old one:
sudo rm -f /usr/local/bin/blocked-sites
rehash
which -a blocked-sitesDirect install script:
System-wide command (recommended):
./install.shUser-only install (no sudo):
./install.sh --userThen verify:
blocked-sites --helpInitialize the managed section and migrate existing manual loopback block entries:
sudo blocked-sites init --migrate-existingGive your user password-less access (run once, then keep sudo out of
blocked-sites for good):
sudo blocked-sites setup-permissionsThis makes /etc/hosts and the data directory owned by your user, and switches
hosts-file writes to in-place updates, so you no longer need sudo for any
blocked-sites command.
Enter the interactive CLI (same as running blocked-sites with no command):
blocked-sites cliSites you have added stay in a persistent list. Each site shows its status; you can check it on/off, delete it, and set timers that count down:
Sites (ON = blocked):
1. [ON] instagram.com blocked until 2026-08-05 23:50:55 AKDT (1h 29m left)
2. [OFF] youtube.com unblocked
3. [ON] reddit.com permanent
> 2 # toggles youtube.com back on
> t 3 # toggles reddit.com off
> d 1 # delete instagram.com (unblocks + forgets it)
> tm 2 90m # timed block on youtube.com
> s # show timer status
After setup-permissions, sudo is not required for any of these commands.
List blocked domains:
blocked-sites listAdd domains (plain domain or full URL):
blocked-sites add instagram.com g2a.com
blocked-sites add 'https://reddit.com/r/all'Add temporary blocks:
# Flexible duration formats (case-insensitive)
blocked-sites add instagram.com --for 90m
blocked-sites add youtube.com --for 1M
blocked-sites add x.com --for 1MIN
blocked-sites add reddit.com --for 1H
blocked-sites add facebook.com --for 1MO
blocked-sites add news.ycombinator.com --for 2H30M
# Block until a specific local/ISO time
blocked-sites add twitch.tv --until "2026-04-12 18:30"
# If already permanently blocked, convert it to temporary for this timer
blocked-sites add instagram.com --for 1H --convert-permanentCheck timed block status:
blocked-sites statusClean up expired timers (this command performs automatic unblocking):
blocked-sites cleanup-expiredIf you request a timed block for domains that are already permanently blocked,
the CLI will warn you. In an interactive terminal it asks for confirmation; in
non-interactive use, pass --convert-permanent to explicitly allow conversion.
Remove by domain:
blocked-sites remove instagram.comInteractive remove (numbered picker):
blocked-sites removeSee backups:
blocked-sites backupsRestore from a backup:
blocked-sites restore ./backups/hosts.YYYYMMDD-HHMMSS-ffffff.bak- Uses a managed marker block in hosts:
# >>> blocked-sites-manager start >>># <<< blocked-sites-manager end <<<
- Defaults to adding both:
127.0.0.1 domain + www.domain::1 domain + www.domain
- Blocks exact hostnames (
domainandwww.domainby default), not all subdomains. - Keeps other non-managed hosts entries intact.
- Automatically creates a backup before any write.
- Timed blocks are tracked in a state file and removed by
cleanup-expired.
# Preview without writing
blocked-sites add youtube.com --dry-run
# Do not add www variant
blocked-sites add github.com --no-www
# IPv4-only or IPv6-only
blocked-sites add x.com --ipv4-only
blocked-sites add x.com --ipv6-only
# Remove only exact host, not www.<host>
blocked-sites remove x.com --exact
# Preview timed block creation without writing
blocked-sites add x.com --for 1H --dry-run
# Preview expired cleanup without writing
blocked-sites cleanup-expired --dry-run
# Use a custom hosts file for testing
./blocked_sites.py --hosts-file ./hosts.test --backup-dir ./backups.test --state-file ./timers.test.json init- One-time
sudo blocked-sites setup-permissionsremoves the need for sudo. - Default backups path:
/etc/blocked-sites-manager/backups
- Default timer state file:
/etc/blocked-sites-manager/timers.json
- Site list used by the interactive CLI:
/etc/blocked-sites-manager/sites.json
MO/MONTHdurations are treated as 30-day months.