I live in tmux and Zellij. The second I leave the terminal all that muscle memory is useless. Prefix key, split, hjkl to move around, switch tabs — none of it works on Brave or Slack or anything else. So I built Tessera to get it back.

Windows and layouts, or sessions

There are already decent tiling window managers on macOS — yabai, Amethyst, AeroSpace. I tried them. They all think in windows and layouts: here’s a grid, your window goes in it. yabai’s best features also want SIP disabled, which is not something I’m doing on a work machine.

I wanted something that thinks in sessions, the way a multiplexer does. In Tessera a tab is its own workspace, and when you split a pane, a fuzzy-search palette opens in the empty half so you pick what goes there.

I read through the source of Zellij, AeroSpace and paneru before starting. None of them have the per-pane picker. That’s the part I think is actually new.

macOS has no window manager API

That’s the whole difficulty. Everything goes through the Accessibility API, which was designed for screen readers, so you end up puppeting apps that really don’t want to be puppeted. Three problems ate most of my time.

Chromium and Electron apps accept a resize, then quietly snap back

Brave, VS Code, Slack — all of them. They set AXEnhancedUserInterface, so Tessera switches it off around each resize and puts it back afterwards.

The Accessibility grant is tied to your code signing identity

With ad-hoc builds that means re-granting permission on every single rebuild, which gets old fast. The app now generates a per-user self-signed certificate and re-signs itself on first launch, so the grant survives a brew upgrade and you don’t need an Apple Developer ID.

kAXHidden works per application, not per window

That falls apart for virtual tabs the moment one app has windows in two different tabs. Tessera parks the stray windows off screen instead of hiding the whole app.

Keeping the core testable

The layout code — BSP tree, fuzzy matcher, pane navigation — lives in a pure CoreGraphics core with no AppKit in it. TesseraCore imports CoreGraphics and Foundation, nothing else.

That’s what makes it testable: all 48 tests across 6 suites run without launching the app or touching the Accessibility permission.

swift test    # 48 tests in 6 suites, no app, no permission prompt

No polling loop

There isn’t one anywhere. Layout enforcement runs off Accessibility observer events, so it does nothing at all until a window actually moves.

After a day of uptime it was sitting at 24 MB, having burned 3 seconds of CPU in total. Window count doesn’t seem to matter much either — a fresh instance managing 12 windows across 3 tabs uses 11 MB.

Install

brew tap pa/tessera
brew trust pa/tessera      # one-time; Homebrew makes you trust third-party taps
brew install tessera
brew services start tessera

Then grant System Settings → Privacy & Security → Accessibility → Tessera. It’s a menu-bar agent — look for the glyph. There’s no Dock icon and nothing in Launchpad.

Default prefix is ⌃⌥⌘. Full key reference is on the documentation site.

About the code

I’ll be upfront about this: a lot of it was built with Claude Code, and the commit history makes that obvious anyway. The architecture, the session model, the call not to rewrite the Accessibility layer in Rust, and most of the debugging were mine.

Known problems

  • One display only. Everything assumes the main screen. Per-display layouts are what I’m working on next.
  • macOS 15+. The Homebrew bottle is Apple Silicon only, so Intel machines compile from source and that takes a few minutes.
  • Stage Manager has to be off. It hides inactive apps’ windows and fights every tiling WM.
  • Apps with a minimum window size overflow their pane. A pure-Accessibility window manager can’t force a window below the size an app will accept — only SIP-disabled approaches can. Tessera anchors it at the pane origin and lets it overflow rather than faking a fit.

It’s a couple of weeks old. I’d really like to hear where it falls over — issues welcome.