Azimuth is a keyboard-driven window manager for macOS, built with Swift and AppKit. It lives in the menu bar and lets you place, resize, move, and throw the focused window across your screens with predictable shortcuts — no mouse, no guesswork.
Design principle: predictability over clever inference. Every command does exactly one well-defined thing, and effects compose. If you can get a result by combining simple commands, Azimuth doesn't add a separate "smart" feature for it.
- Halves & snap-throw — snap the window to a screen half; press again toward the same edge to throw it to the adjacent display.
- Thirds & two-thirds — left/center/right and top/middle/bottom, horizontally or vertically.
- Maximize / center — fill the work area or center at the current size.
- Maximize with gaps — fill the work area but leave a uniform inset on all sides (
⌃⌥⇧↩). - Move (keep size) — nudge the window one step in any direction, clamped to the work area.
- Relative shrink — shrink the window to 1/2 or 2/3 of its current size against a pinned edge (not the screen). Effects compose: 2/3 then 1/2 lands on 1/3.
- Move to next display — send the window to an adjacent monitor, preserving its shape and relative position.
- Undo — restore the previous frame, one step per window.
- Multi-monitor aware — position-aware adjacent-display selection (the window goes to the monitor that lines up with where it currently is).
- Two presets — Standard (arrow keys) and Vim (HJKL), each fully customizable with conflict warnings.
- Automatic updates — Azimuth checks for new releases and updates in place (via Sparkle), or check on demand from the menu. Updates are Apple-notarized and EdDSA-signature verified.
- macOS 14 (Sonoma) or later.
- Accessibility permission (Azimuth controls other apps' windows through the Accessibility API).
Azimuth runs entirely on your Mac. It collects no data, has no telemetry or analytics, and makes no network connections other than checking for updates (Sparkle). The Accessibility permission is used solely to move and resize the windows of the app you're using.
- Download the latest
Azimuth-<version>.dmgfrom the Releases page. - Open the DMG and drag Azimuth into your Applications folder.
- Launch it, then enable Azimuth in System Settings → Privacy & Security → Accessibility.
The build is Developer ID–signed and notarized, so it opens without Gatekeeper warnings.
brew install --cask ai-screams/tap/azimuthThen enable Azimuth in System Settings → Privacy & Security → Accessibility. Updates are handled in-app (Sparkle), so brew upgrade won't fight the built-in updater.
git clone https://github.com/ai-screams/Azimuth
cd Azimuth
make runmake run builds and launches a properly code-signed build (Apple Development identity), which keeps your Accessibility grant stable across rebuilds. make build is ad-hoc signed (compile/CI checks only) and not for daily use.
On first launch, open System Settings → Privacy & Security → Accessibility and enable Azimuth. The menu bar item and the Settings window both show the current permission state and a shortcut to the right settings pane.
Azimuth has no installer, so removing it is just a few steps:
- Quit Azimuth, then drag it from Applications to the Trash.
- Remove its Accessibility entry: System Settings → Privacy & Security → Accessibility → select Azimuth → click −. macOS keeps this entry even after an app is deleted, and no app can remove its own entry through the system — so this step is manual (the same is true for every app that uses Accessibility).
- (Optional) delete its preferences:
defaults delete com.aiscream.Azimuth
If you enabled Launch at login, that registration is cleared automatically once the app is removed.
Azimuth separates command groups by modifier layer:
| Layer | Purpose |
|---|---|
⌃⌥ (Control+Option) |
Halves (snap/throw) · Maximize · Center · Undo · Thirds & two-thirds (number keys) |
⌃⌥⌘ |
Move (keep current size) |
⌃⌥⇧ |
Relative shrink — ½ on arrows, ⅔ on M , . / |
⌃⌥⌘⇧ |
Move to next display |
| Group | Command | Shortcut |
|---|---|---|
| Halves (snap + throw) | Left / Right | ⌃⌥← / ⌃⌥→ |
| Top / Bottom | ⌃⌥↑ / ⌃⌥↓ |
|
| Maximize · Undo · Center | Maximize | ⌃⌥↩ (Return) |
| Maximize · Undo · Center | Maximize with gaps | ⌃⌥⇧↩ (Return) |
| Undo | ⌃⌥⌫ (Delete) |
|
| Center | ⌃⌥C |
|
| Thirds (1/3) | Horizontal left·center·right | ⌃⌥1 / ⌃⌥2 / ⌃⌥3 |
| Vertical top·middle·bottom | ⌃⌥4 / ⌃⌥5 / ⌃⌥6 |
|
| Two-thirds (2/3) | Horizontal left·right | ⌃⌥7 / ⌃⌥8 |
| Vertical top·bottom | ⌃⌥9 / ⌃⌥0 |
|
| Move (keep size) | Left·Right·Up·Down | ⌃⌥⌘← / → / ↑ / ↓ |
| Relative shrink (½) | Left·Right·Up·Down | ⌃⌥⇧← / → / ↑ / ↓ |
| Relative shrink (⅔) | Left·Down·Up·Right | ⌃⌥⇧ M , . / |
| Move to next display | Left·Right·Up·Down | ⌃⌥⌘⇧← / → / ↑ / ↓ |
Only the directional commands and Undo change keys; everything else (Maximize, Center, numbers) matches Standard.
| Difference | Mapping |
|---|---|
| Direction | H = left, L = right, K = up, J = down |
| Undo | U |
Example: ⌃⌥H (left half) · ⌃⌥⌘K (move up) · ⌃⌥⇧J (shrink to bottom half) · ⌃⌥⌘⇧L (move to right display) · ⌃⌥U (undo).
If a combination is already claimed by the system or another app, Azimuth's registration is skipped and the Settings window marks it "In use by system." Every shortcut can be remapped in Settings.
- Maximize — fills the work area (visible area minus menu bar and Dock).
- Maximize with gaps — like Maximize, but leaves a uniform 12pt inset on all four sides so the window doesn't touch the screen edges. Falls back to a plain maximize if the work area is too small for the gap.
- Thirds / two-thirds — axis-independent: horizontal commands change only x/width, vertical only y/height, so they compose (e.g. horizontal-third then vertical-third → a corner cell).
- Halves + throw — if the window isn't already in that half, it snaps there. If it is, Azimuth throws it to the adjacent display in that direction and places it in the opposite half (throwing right lands it in the target's left half). No adjacent display → it stays put.
- Move — keeps the current size and nudges the window by its own width/height, clamping at the work-area edge. It never resizes or changes display; repeated presses push it to the edge.
- Center — keeps size, centers in the work area.
- Relative shrink (½ / ⅔) — based on the current window, not the screen: pins the chosen edge and shrinks toward it. Arrow keys shrink to ½;
M , . /shrink to ⅔ (M=left, ,=down, .=up, /=right). Effects compose: ⅔ then ½ lands on ⅓. - Move to next display — preserves shape, relative position, and size (capped/clamped so it never exceeds the target screen). No adjacent display → stays put.
- Undo — restores the previous frame (one step per window). Display reconfiguration discards undo history.
- Failure feedback — a beep on failure (toggleable in Settings) plus a log entry. Transient failures during Space switches or animations are skipped silently.
Note: apps with size increments (e.g. Terminal) may leave a sub-row gap when snapped to a half/maximize, because they round down to their character grid. The work area excludes the menu bar and Dock, so a gap at those edges is expected.
Open Settings from the menu bar item or with ⌘,:
- Switch preset (Standard / Vim).
- Record custom shortcuts per command, with conflict warnings and per-command Reset.
- Enable/disable command groups, or unbind individual commands.
- Toggle failure beep, launch-at-login, and hide the menu bar icon.
- Automatic updates via Sparkle — current version + Check for Updates… in Settings (and the menu bar / App menu).
If the menu bar icon is hidden, relaunching Azimuth reopens the Settings window so you always have a way back in.
| Version | Theme |
|---|---|
| v1 | Stabilization across representative apps — shipped / stable |
| v1.5+ | Anchor placement: snap/size the window relative to another window (same display) |
| v2 | Workspaces: per-app default positions, named scene save/restore |
| v3 | Automation: URL scheme, Shortcuts action, per-app rules |
Azimuth uses:
SwiftLintfor lintingSwiftFormatfor formatting.editorconfigfor basic editor consistency
Install the tools with Homebrew:
brew install swiftlint swiftformat gitleaksCommon make targets, run from the project root:
make run # build a signed app and launch it (use this to actually run Azimuth)
make build # compile-only verification (ad-hoc signed; CI/compile checks only)
make test # run the pure-logic command-engine tests (swiftc)
make lint # SwiftLint (strict)
make format # SwiftFormat
make secrets # gitleaks secret scanXcode also runs SwiftLint during builds when it is installed locally. If SwiftLint is missing, the build shows a warning instead of failing.
Install the local Git hooks once:
make install-hooksThe pre-commit hook runs SwiftFormat --lint and SwiftLint --strict.
GitHub Actions runs the same lint checks and a macOS xcodebuild build on pushes to main and on pull requests. It also runs gitleaks secret scanning and uploads a SARIF report to GitHub code scanning.
Azimuth is free and open source — no paywall, no ads, no telemetry — and it always will be. If it earns a place in your workflow, you can chip in to fund its development:
- 💛 Ko-fi — a one-time tip or a supporter license · ♥ GitHub Sponsors — recurring support
A supporter license is simply a way to say thanks — it unlocks nothing, because every feature is already free for everyone. Entirely optional, always appreciated: there is no paywall and never will be.
Apache License 2.0 — see LICENSE and NOTICE.
Copyright 2026 AiScream. "Azimuth" and the project name/branding are not granted under the license (Apache-2.0 does not grant trademark rights).