The obvious way to build a blink reminder is to point the camera at the user. Run face landmark detection, measure eye aspect ratio, count blinks per minute, and prompt only when the rate drops. It is a clean idea. It is also the version of this app we decided not to build, and the reasoning is worth writing down.
What the camera would cost
A permission you cannot walk back
Camera access on macOS is a single binary decision made at first launch, and it is the highest-friction prompt in the system. A large share of people decline it, and a meaningful share of those uninstall rather than decline — a menu bar utility asking for the camera reads as suspicious even when it is not.
There is no partial version of this permission. An app that can measure your blink rate can see your face, your room, and whoever walks behind you.
The indicator light
macOS lights the camera indicator whenever the camera is in use, by hardware, with no software override. A blink detector needs the camera continuously. That means a green light next to your screen for eight hours a day, every day.
This is a genuinely good security design and it makes the product unusable. Nobody wants a background utility that keeps the camera light on through a workday, and nobody should have to be reassured about it repeatedly.
Battery and heat
Continuous video capture plus per-frame inference is not free. Even with the Neural Engine doing the work, you are keeping the camera powered, decoding frames, and running a model at several frames per second for the entire working day. On a laptop that is measurable battery, and on a fanless Mac it is measurable heat.
A reminder app has a strict budget: it must cost less than the problem it solves. Skopia's timer path is a one-second tick and a two-second context poll — a rounding error in Activity Monitor.
It stops working exactly when you need it
Camera access on macOS is largely exclusive in practice. During a video call — a long stretch of concentrated screen time — the camera belongs to Zoom or Meet, and your blink detector is blind. Same story with the lid closed on an external monitor, or a physical camera cover, which plenty of people use.
What a timer gives up
We should be straight about the trade. A fixed-interval reminder does not know whether you blinked. It cannot adapt to you. It fires on a schedule whether you needed it or not.
Two things make that acceptable. First, the base rate: during focused screen work, blink rate is reduced for essentially everyone, essentially all the time. A prompt is rarely wrong. Second, the mechanism of action — what makes blink training work is an external cue that interrupts task absorption. That is the active ingredient, and a timer delivers it. Measuring the rate would produce a better-targeted prompt, not a different kind of prompt.
Skopia is a prompt, not a measurement. It is honest about which of those it is.
The problem worth solving instead
People do not abandon break apps because the prompts are badly targeted. They abandon them because a prompt appeared during a presentation, or over a film, or in the middle of a screen recording.
Interrupting at the wrong moment is not a minor annoyance. It is the single failure that gets this category of app deleted. So the engineering went there instead — and, as it turns out, knowing whether you should be interrupted needs no camera and no permissions at all.
How Skopia reads context without asking for anything
Five conditions suspend reminders. Each uses a public, read-only API that returns metadata, never content.
On a call — CoreAudio
Skopia asks CoreAudio's hardware abstraction layer which processes currently hold the microphone. On macOS 14.4 and later the system reports per-process input state, which also identifies the app; older systems fall back to a per-device "in use somewhere" flag.
It reads device and process metadata, never audio. There is no microphone permission prompt, because no audio is ever captured — the app has no more access to what you are saying than the microphone indicator in your menu bar does. Raw readings pass through a small state machine that requires several consecutive readings in the same direction before it changes state, so a system sound does not register as a meeting.
Full screen — the window list
A public window-list call returns each on-screen window's geometry and owning application. If a window matches a screen's full dimensions, something is in full screen. The one field in that API that is gated behind Screen Recording permission is the window's title — and Skopia never reads it. Geometry and owner name need no permission at all.
Screen recording — an absence, not a signal
This one required a genuinely annoying amount of work. The built-in macOS recorder (⇧⌘5) creates no power assertion, and its stop button lives in the menu bar, where the window list cannot see it. There is no direct signal to read.
What there is: the recorder's UI process is not resident. macOS starts it for a capture and quits it afterwards, and both of the other things it does — the ⇧⌘5 control bar and the post-screenshot thumbnail — put a window on screen. So the recorder running with no window visible means a recording is in progress. Both the process list and the window owner list are permission-free.
That trick covers the built-in recorder only. Third-party tools — OBS, Loom, CleanShot X, ScreenFlow and the rest — are caught the same way video playback is: by the display-sleep assertion they hold while recording, matched against a list of known recorder bundle identifiers plus any app you add yourself.
Video playback — power assertions
Anything playing video holds a power assertion to keep the display awake. Skopia reads the same assertion list that pmset -g assertions prints — public IOKit, read-only.
This condition ships switched off by default, which is a deliberate admission that the signal is imperfect. Tools like Amphetamine and caffeinate hold a display-sleep assertion permanently. On by default, they would pause Skopia forever, and the app would look broken rather than considerate. A condition we cannot trust unconditionally is one the user opts into.
Deep focus apps — your own list
A list of applications you choose, in which reminders never fire. No detection, no heuristics, no guessing what matters to you.
What this adds up to
- No privacy permission prompts. Not camera, not microphone, not screen recording, not accessibility. Skopia does not ask, because it does not need to.
- Metadata only. Which process holds a device, which app owns a window, which processes hold a power assertion. No audio, no video, no window titles, no keystrokes.
- Nothing leaves the Mac. No network requests, no account, no telemetry. All state is a handful of local preference keys.
- Runs under the App Sandbox. None of the detection needs an entitlement. The only one involved is read-only access to files you pick yourself, used when you add an app to a pause list.
The honest note about version 2.0
Skopia 2.0 is planned to include real blink detection, on device, using Apple's Vision framework. Having spent this article arguing against the camera, that deserves plain language rather than a footnote.
The commitments, stated in advance:
- It will be opt-in and off by default. The camera is never touched unless you turn it on.
- Detection runs entirely on device. No frame is ever uploaded, stored, or written to disk.
- The timer-only mode stays, permanently, as a first-class way to use the app — not a legacy fallback.
- 2.0 is a free upgrade for everyone who bought 1.x. That is written into our terms, not just our marketing.
The argument here was never that camera-based detection is illegitimate. It is that it should be a choice you make deliberately, with the indicator light and the battery cost understood, rather than the price of entry for a reminder to blink.
Skopia is a quiet Mac menu bar app that reminds you to blink and knows when to stay silent. It requests no privacy permissions at all. $4.99, one-time.
Get Skopia — $4.99 →