Alan draws a colored border around the active window on macOS — or, in spotlight mode, dims everything except it — so you can always see where your input is going.
Important
LLM Disclosure: Much of this code base was written by or with the help of large language models.
Latest release: v3.0.0 · Download
Requires: macOS 15.7 (Sequoia) or later, and the Accessibility permission (Alan walks you through granting it on first launch).
This is a fork of tylerhall/Alan. The fix for windows on secondary displays was contributed back upstream (tylerhall/Alan#10); beyond that, this fork adds:
- Border styling: width, inset, corner radius, light/dark colors, and a style picker — solid, dashed, marching ants, or an xkcd-style hand-drawn wobble.
- An optional stronger drop shadow behind the active window, and an optional glow on the border itself.
- Optional per-app border colors, with each app's hue derived from its bundle identifier — you learn the colors within a day.
- Spotlight mode, the inverse-Alan: instead of a border, everything except the focused window is dimmed (with a dim-level slider).
- A "find my window" hotkey (⌃⌥⌘F by default, recordable) that flashes the border, and an optional shake-the-mouse gesture that does the same.
- An always-available status menu: pause/resume Alan, exclude the frontmost app in one click, open Settings, and hide or show the Dock icon — live, no relaunch.
- An excluded-apps list, for apps that should never get a border.
- Behavior settings: hide the border while dragging, hide it when a window fills its screen, pulse on focus change, and an eased glide when the border moves between windows (with a duration slider). Native full-screen windows never get a border.
- Reduce Motion support across every animation, and overlays that stay out of screenshots, screen recordings, and screen shares.
- Event-driven window tracking via
AXObserver(replacing the original 10 Hz polling), with a short-lived timer to follow live drags. - Launch at login, a live settings preview, party mode 🌈, and CI that builds every push and publishes releases from version tags.
Grab Alan-<version>.zip from the
Releases page, unzip, and move Alan.app to
/Applications. The releases are built on CI and are only ad-hoc signed,
so on first launch right-click the app and choose Open (or run
xattr -d com.apple.quarantine /Applications/Alan.app).
Or build it yourself — open Alan.xcodeproj in Xcode and hit Run, or
from the command line:
xcodebuild build -project Alan.xcodeproj -scheme Alan -configuration Release(./scripts/build.sh wraps the same build with conveniences —
incremental Release build, reveal in Finder, --clean, --run,
--install — but depends on the external
lkm-build tool; plain
xcodebuild needs nothing.)
The releases are only ad-hoc signed (see Install), and macOS ties
the Accessibility permission to an app's code-signing identity. A freshly
downloaded build can therefore present as a "different" app to the system and
lose the grant — so after replacing Alan.app, Alan may stop drawing borders
until you re-authorize it:
- Open System Settings → Privacy & Security → Accessibility.
- If an old Alan entry is listed, remove it (select it, click –).
- Add the new
/Applications/Alan.appand turn it on.
Alan notices this on launch and, if it has held the permission before, says a recent update likely reset it rather than showing the first-run text. Signing with a Developer ID and notarizing would remove this step entirely and is the long-term fix.
Everything lives in the status-bar item (the little window icon): Settings… opens the three-tab settings window (Appearance, Behavior, Excluded Apps), and the menu also has Pause Alan, Exclude “”, and a live Hide Dock Icon toggle.
Every setting is stored in the studio.retina.Alan defaults domain, so
all of it is scriptable — handy for Shortcuts, Stream Deck buttons, or
shell aliases. A few useful ones:
defaults write studio.retina.Alan paused -bool true # pause Alan
defaults write studio.retina.Alan paused -bool false # resume
defaults write studio.retina.Alan borderStyle handDrawn # solid | dashed | ants | handDrawn
defaults write studio.retina.Alan spotlightMode -bool true
defaults write studio.retina.Alan hideDock -bool true # applies on relaunch when set externallyExternal changes are picked up automatically on the next refresh.
MIT, original © 2025 Tyler Hall.
