bobrwm
A tiling window manager for macOS, written in Zig
Features
- Workspaces On Native Spaces (Up To 10)
- BSP And Monocle Layouts
- Built-In Trackpad Swipe Switching
- App-To-Workspace Rules
- Live Config Reload
- Unix Socket IPC With JSON Output
- Stable Workspaces Across Monitors
- Signed And Notarized App Bundle
Install
$brew trust bobrwm/tap && brew install --cask bobrwm/tap/bobrwmAbout
bobrwm is a BSP tiling window manager for macOS, written in Zig, that binds each of its workspaces to a native Mission Control Space and switches between them with a synthetic Dock gesture. It runs as a signed menu-bar app, is configured through a live-reloadable ZON file, and exposes every action over a Unix socket IPC client.
Who It's For
bobrwm is for macOS developers who want an i3-style binary space partitioning tiler that works with native Mission Control Spaces instead of replacing them, and who are comfortable with a young, fast-moving project written in Zig. It suits users who are happy editing a ZON config file and scripting window behaviour from the terminal over IPC, rather than clicking through a GUI.
How It Works
Each bobrwm workspace is assigned to exactly one ordinary Mission Control Space. At startup the primary display gets the lowest workspace numbers in native order, so bobrwm workspace 1 is native Space 1, and secondary displays follow with at least one workspace each. Those bindings then stay fixed: switching, moving windows, and unplugging or reconnecting a monitor never renumber workspaces, so keybinds and app rules keep pointing at the same windows. When a monitor goes away its workspaces move to the remaining displays. bobrwm creates missing Spaces on the primary display, removes extra Spaces only when they're empty, and re-reconciles if you add or delete Spaces while it runs. Switching uses the high-velocity synthetic Dock gesture pioneered by InstantSpaceSwitcher, and window moves and topology queries go through private, undocumented APIs. The project warns that either path can break on a future macOS release.
Within a workspace, windows are tiled with BSP by default, or with a monocle layout. The BSP tree can be tuned from the CLI: insert point, relative or absolute split ratios, mirroring, rotation, equalize, and balance. The app itself (Bobrwm.app) runs as a menu-bar agent with a Swift/AppKit shell around the Zig core. The bobrwm command is a separate lightweight client that forwards every command to the app over a Unix socket, and queries for windows, workspaces, displays, and apps can return JSON. Trackpad switching is built in: bobrwm intercepts the native horizontal Spaces swipe and jumps to the adjacent bobrwm workspace, reusing its Accessibility grant.
Configuration
// ~/.config/bobrwm/config.zon
.{
.workspace_names = .{ "term", "web", "code", "chat" },
.gaps = .{ .inner = 4, .outer = .{ .left = 4, .right = 4, .top = 4, .bottom = 4 } },
.keybinds = .{
.{ .key = "h", .mods = .{ .alt = true }, .action = .focus_left },
},
.app_rules = .{
.{ .app_id = "com.apple.Safari", .workspace = 2 },
},
}
Compared to Alternatives
Compared to AeroSpace, which runs its own virtual workspace system that bypasses macOS Spaces, bobrwm now maps workspaces directly onto native Spaces. That keeps Mission Control and the native swipe gesture meaningful, but it relies on private APIs that may break with macOS updates. Compared to yabai, which also works with native Spaces but needs SIP partially disabled for some features, bobrwm drives Space switching through a synthetic Dock gesture and private APIs. Its README doesn't mention disabling SIP. Both yabai and bobrwm expose a CLI over a socket, but bobrwm is configured with a declarative ZON file rather than a shell script.
Requirements
- Accessibility permission required. It's tied to the code signature, so users upgrading from the old Homebrew formula must grant it again.
- At least as many ordinary Mission Control Spaces as bobrwm workspaces, with at least one per managed display (bobrwm creates missing ones on the primary display)
- Uses private macOS APIs for Space switching and window moves; on macOS 27 and later it supplies the extra IOHID payload Dock now requires
- Signed, notarized, and stapled, so Gatekeeper runs it without extra steps
- Early development: the cask tracks
mainand publishes a fresh build on every push instead of tagged releases
Getting Started
Install with brew trust bobrwm/tap && brew install --cask bobrwm/tap/bobrwm. Homebrew 6 won't load third-party casks until the tap is trusted. If you previously used the formula with bobrwm service install, remove the old launchd agent by hand first. Launch Bobrwm.app from Spotlight or with open -a Bobrwm, and grant Accessibility access. Generate a fully documented starting config with bobrwm show-config --default --docs > ~/.config/bobrwm/config.zon, and list every keybind action with bobrwm list-actions --docs. Apply edits with Alt+Shift+R or bobrwm reload-config. Set .start_at_login = true to run at login, and enable trackpad switching with .swipe = .{ .enabled = true }. Full documentation is at github.com/bobrwm/bobrwm.