AeroMux is a macOS menu bar companion for AeroSpace. It adds a persistent left sidebar so you can see your non-empty workspaces, spot the focused window, and jump directly to a window without leaving your tiling workflow.
- Shows non-empty AeroSpace workspaces in a persistent sidebar
- Highlights the focused workspace and focused window
- Lists windows by app name and title
- Lets you click a window row to focus it through the AeroSpace CLI
- Supports standard and floating window modes
- Lets you change sidebar width, window transparency, compact mode, workspace ordering, launch-at-login, and keyboard shortcuts from the menu bar
- Supports local workspace titles and descriptions
- Polls AeroSpace every second by default, with an optional localhost refresh hook for lower-latency updates
AeroMux starts in standard window mode.
Standard mode is the integrated layout. AeroMux expects AeroSpace to reserve a left gap at least as wide as the sidebar. When the gap is configured correctly, the sidebar uses a normal window level and tiled windows stay out of its way.
Floating mode is the zero-config layout. AeroMux keeps the sidebar floating above normal windows, AeroSpace leaves it alone instead of tiling it, and sidebar width no longer depends on outer.left. This is simpler to try, but it can cover tiled windows.
Window transparency is independent of window mode. It fades the sidebar background while keeping labels and window text fully opaque.
You can switch modes from the menu bar:
AeroMux menu bar icon -> Window Mode -> Standard
AeroMux menu bar icon -> Window Mode -> Floating
For the best standard-mode experience, reserve a left gap on your main monitor:
[gaps]
outer.left = [{ monitor.main = 260 }, 0]260 is AeroMux's default sidebar width. If you change the sidebar width from the menu bar or in settings.json, keep the standard-mode outer.left value at least that large.
If AeroMux cannot confirm a large enough gap in standard mode, it falls back to a floating overlay and shows an integration warning in the sidebar.
- macOS 13 or newer
- AeroSpace installed and already working
aerospaceavailable onPATHin the environment that launches AeroMux- A Swift 6 toolchain if you build from source
Quick checks:
sw_vers -productVersion
aerospace --version
which aerospace
swift --versionIf which aerospace prints nothing, AeroMux will not be able to read or focus AeroSpace windows from that launch environment.
The preferred install path is the latest DMG from GitHub Releases.
Release builds are Developer ID-signed and notarized by Apple. Open the DMG, drag AeroMux.app into Applications, and launch it.
git clone https://github.com/raghavendra-talur/aeromux.git
cd aeromux
swift build
swift runAeroMux launches as a background-style accessory app and opens the sidebar window.
To build and run the executable yourself:
swift build
./.build/debug/AeroMuxStop a foreground run with Ctrl-C.
To launch in the background:
./.build/debug/AeroMux &Stop a background run with:
pkill AeroMuxThe AeroMux menu bar item is the main control surface:
- Show Sidebar / Hide Sidebar toggles the sidebar window
- Sidebar Width sets a whole-number width from
100to600pixels - Window Transparency fades the sidebar background from
0to65percent while keeping text fully opaque - Window Mode switches between standard and floating behavior
- Pin Active Workspace First moves the focused workspace to the top
- Compact Mode uses a denser sidebar layout
- Launch at Login asks macOS to start AeroMux automatically
- Keyboard Shortcuts... opens the shortcut recorder
- Refresh Now asks AeroMux to reread AeroSpace state immediately
- Quit AeroMux exits the app
There is no default global shortcut. To set one:
- Click the AeroMux menu bar icon.
- Choose Keyboard Shortcuts....
- In the AeroMux Shortcuts window, record a shortcut for Toggle Sidebar.
Once set, the shortcut toggles the sidebar from any app. The current shortcut also appears next to Show Sidebar or Hide Sidebar in the menu bar.
Each workspace card has an edit button. Use it to set a local title and optional description for that AeroSpace workspace.
Custom titles and descriptions are stored in workspaces.json. AeroMux still keeps the original AeroSpace workspace name, and shows it as Workspace <name> when a custom title is present.
AeroMux stores user-editable files under:
~/.config/aeromuxIf XDG_CONFIG_HOME is set, AeroMux uses:
$XDG_CONFIG_HOME/aeromuxCreated automatically on first launch:
{
"compactMode": false,
"launchAtLogin": false,
"pinActiveWorkspaceFirst": false,
"sidebarWidth": 260,
"windowMode": "standard",
"windowTransparency": 0
}Keys:
sidebarWidth: sidebar width in pixels, clamped to whole numbers from100to600windowMode:standardorfloatingwindowTransparency: background transparency percentage from0to65compactMode: denser sidebar text and spacingpinActiveWorkspaceFirst: move the focused workspace to the toplaunchAtLogin: register or unregister AeroMux with macOS login items
Changes made through the menu bar apply immediately. Manual file edits are picked up the next time AeroMux launches.
Created automatically as AeroMux discovers workspaces:
{
"workspaces": [
{
"workspace": "1",
"title": "1",
"description": null
}
]
}Keys:
workspace: exact AeroSpace workspace nametitle: label shown in the sidebar instead ofTask <workspace>description: optional detail line under the title
Polling works without extra setup. For faster updates after AeroSpace events, call AeroMux's local refresh endpoint:
curl -fsS -X POST http://127.0.0.1:39173/refresh >/dev/null 2>&1 || trueA helper script is included at scripts/aerospace-refresh-hook.sh.
The listener binds only to 127.0.0.1:39173.
AeroMux currently calls:
aerospace list-workspaces --focused --jsonaerospace list-workspaces --focused --format %{workspace}aerospace list-windows --focused --jsonaerospace list-windows --all --format %{window-id}\t%{app-name}\t%{window-title}\t%{workspace}\t%{app-bundle-id}aerospace list-monitors --focused --jsonaerospace focus --window-id <id>aerospace config --config-path
If a future AeroSpace release changes those flags or output formats, AeroMux may need updates.
Make sure aerospace is installed and visible on PATH for the process that launches AeroMux:
which aerospace
aerospace --versionIf AeroSpace works in one shell but not another, fix your shell startup files or launch AeroMux from an environment where aerospace resolves correctly.
If window mode is set to floating, this is expected.
If window mode is set to standard, one of these is likely true:
outer.leftis not configured- the reserved left gap is smaller than the sidebar width
- AeroMux could not read your AeroSpace config path
Start with:
aerospace config --config-pathThen confirm your config contains a left gap reservation like:
[gaps]
outer.left = [{ monitor.main = 260 }, 0]If you changed sidebarWidth, use that number instead of 260.
Your installed AeroSpace CLI may not support aerospace focus --window-id <id> yet, or the flag may have changed.
Try:
aerospace focus --helpIf that flag is unsupported, AeroMux can still display state but window focusing will fail.
Check that:
- AeroSpace is running
- a workspace is focused
- at least one managed window is open
aerospace list-windows --allreturns output in your shell
- Main monitor only
- Left sidebar only
- No Preferences window yet
- No published compatibility matrix yet for Intel Macs or multiple AeroSpace versions
This is not a full compatibility matrix. It is the environment currently verified in this repository:
- macOS 26.2 (
BuildVersion 25C56) - Apple Silicon
arm64 - AeroSpace
0.20.3-Beta(6dde91ba43f62b407b2faf3739b837318266e077) - Apple Swift
6.2.3
Useful local commands:
swift build
swift test
make appmake app creates a packaged app at:
dist/AeroMux.appGeneral contributor workflow is documented in docs/DEVELOPMENT.md. Release packaging is documented in docs/RELEASING.md.
Issues and compatibility reports are useful, especially for:
- macOS version differences
- Intel Mac behavior
- AeroSpace version compatibility
- refresh-hook integration examples
- packaging and app lifecycle ideas
