Skip to main content

CLI focus blocker for macOS — block distracting websites and apps

Project description

Lockin

A CLI focus blocker for macOS. Blocks distracting websites and apps at the network level so you can actually get work done.

  • Blocks websites via /etc/hosts (not a browser extension — works across all browsers)
  • Kills distracting app processes (Discord, Spotify, etc.)
  • Tamper-resistant: sessions cannot be stopped early, even with sudo
  • Enforced by a launchd watchdog daemon that re-applies blocks every 3 seconds
  • Survives reboots, browser restarts, and DNS flushes

Install

pip install lockin

Or with pipx (recommended):

pipx install lockin

Requires macOS and Python 3.11+.

Concepts

There are three layers: presets, profiles, and sessions.

Presets (built-in)       Profiles (you create)        Sessions (you start)
┌──────────────┐         ┌────────────────────┐        ┌──────────────────┐
│ social       │────┐    │ "work"             │        │ active session   │
│ entertainment│────┼───>│  presets: social,   │──────> │  profile: work   │
│ news         │    │    │    entertainment    │        │  duration: 2h    │
│ gaming       │    │    │  custom: slack.com  │        │  96 domains      │
└──────────────┘    │    │  apps: Slack        │        │  3 apps          │
                    │    └────────────────────┘        └──────────────────┘
                    │    ┌────────────────────┐
                    └───>│ "study"            │
                         │  presets: social,   │
                         │    news, gaming     │
                         └────────────────────┘
  • Presets are built-in bundles of sites and apps grouped by category (social media, entertainment, etc.). You can't edit them — they're just building blocks.
  • Profiles are blocking configs you create. A profile picks one or more presets and optionally adds custom sites/apps on top. Think of it as "what do I want blocked when I'm doing X?"
  • Sessions are timed activations of a profile. Once started, a session is locked in — no stopping, no editing, no cheating.

Quick Start

# 1. Create a profile that combines presets
lockin profile create work --preset social --preset entertainment

# 2. Start a 2-hour focus session with that profile
sudo lockin start work --duration 2h

# 3. Check remaining time
lockin

That's it. For the next 2 hours, social media and streaming sites are unreachable and Discord/Spotify get killed on launch.

Presets

Built-in categories you can mix into profiles. Run lockin preset to see them:

Preset Sites Apps
social x.com, twitter.com, facebook.com, instagram.com, tiktok.com, reddit.com, threads.net, snapchat.com, linkedin.com Discord
entertainment youtube.com, netflix.com, twitch.tv, hulu.com, disneyplus.com, primevideo.com, spotify.com Spotify
news news.ycombinator.com, cnn.com, bbc.com, nytimes.com, theguardian.com
gaming steampowered.com, store.steampowered.com, epicgames.com, riotgames.com Steam, Epic Games Launcher

Each domain is also blocked with subdomain variants (www, m, api, mobile, app).

Commands

Profiles

Profiles define what to block. Combine presets with custom sites and apps:

# Block social + entertainment (presets only)
lockin profile create work --preset social --preset entertainment

# Block social + a custom site + an app
lockin profile create coding --preset social --site chatgpt.com --app Slack

# Block everything
lockin profile create lockdown --preset social --preset entertainment --preset news --preset gaming

lockin profile list                           # List all profiles
lockin profile show work                      # See exactly what a profile blocks
lockin profile delete old-profile

Sessions

sudo lockin start work --duration 2h         # Start a focus session
sudo lockin start coding --duration 30m      # Short sprint
lockin status                                # Check remaining time (or just `lockin`)
lockin stop                                  # Refused during active sessions (by design)

Always-Blocked

Block domains permanently, outside of any session:

lockin block reddit.com
lockin unblock reddit.com

Schedules

lockin schedule create mornings --profile work --days mon,tue,wed,thu,fri --start 09:00 --duration 120
lockin schedule list
lockin schedule delete mornings

Other

lockin apps                                   # List detected macOS apps
sudo lockin install                           # Install watchdog daemon
sudo lockin uninstall                         # Uninstall daemon (only when no active session)
lockin --version

How It Works

  1. Website blocking: Writes blocked domains to /etc/hosts pointing to 0.0.0.0, then sets the system immutable flag (chflags schg) to prevent edits
  2. App blocking: Kills blocked apps via osascript (graceful quit) then killall (force kill)
  3. Watchdog daemon: A launchd daemon (KeepAlive: true) runs every 3 seconds to re-apply blocks if tampered with, re-kill blocked apps, and clean up when the session expires
  4. Session signing: Sessions are signed with HMAC-SHA256 (key derived from hardware UUID). Modifying the session file invalidates the signature

Tamper Protection

The whole point of Lockin is that you cannot bypass it during a session:

Attack Mitigation
Edit /etc/hosts Immutable flag (schg) blocks writes; watchdog re-applies if removed
Kill the watchdog launchd auto-respawns it immediately
sudo lockin stop --force No code path exists to stop active sessions
Delete the session file Blocks become permanent (no valid session = no cleanup)
Change the end time in session file HMAC validation fails, watchdog ignores it
Reboot Session persists at /var/lockin/, daemon has RunAtLoad: true
Change system clock Watchdog cross-checks elapsed time vs 2x duration

Configuration

Profiles and schedules are stored in ~/.config/lockin/config.json. Sessions are stored in /var/lockin/session.json.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lockin-0.1.2.tar.gz (42.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lockin-0.1.2-py3-none-any.whl (17.9 kB view details)

Uploaded Python 3

File details

Details for the file lockin-0.1.2.tar.gz.

File metadata

  • Download URL: lockin-0.1.2.tar.gz
  • Upload date:
  • Size: 42.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.6

File hashes

Hashes for lockin-0.1.2.tar.gz
Algorithm Hash digest
SHA256 f21b744de564c99a74e4428d1675024638053922e063b00a32a4b5ad3df38475
MD5 12af3882d6cf0e6113b510e6b238865d
BLAKE2b-256 a4f2e46dc6facc00def4ad2272a9066e49e7f731b2eed158ddd82c734f5e638d

See more details on using hashes here.

File details

Details for the file lockin-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: lockin-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 17.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.6

File hashes

Hashes for lockin-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 93184c48fb684ed829e90d28bca9b1570c7f99fa73b787f535e9c3ad21109d89
MD5 a226cc78198cab198e95651beacbfcd4
BLAKE2b-256 3db76b953ef25247fb4c2e5a5b3313e0e6824b22da0e6d8a3fca4a01af7c1544

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page