mimi

A CLI for macOS windows and spaces, with SIP left on

Category
Window Manager
WM Type
hybrid
License
free
Open Source
Yes
Keybindings
Yes
Scripting
Yes
Last Update
2026-10-25

Features

  • Native Spaces Switching
  • Move, Resize & Focus Windows
  • Language-Agnostic Tiling Layouts
  • Hooks For App & Space Events
  • Window Border Outlines
  • Menu Bar Space Indicator
  • JSON Desktop Queries
  • Works With Any Hotkey Tool

About

mimi is a command-line tool that switches native macOS Spaces and moves, resizes, and focuses windows, with SIP left on. Actions work directly from the CLI as plain shell commands, while an optional background daemon adds hooks, window borders, a menu bar indicator, and optional animated auto-tiling using your own layout scripts. It's written in Go and is currently in early development.

Who It's For

mimi is for developers who want yabai-style scriptable window and Spaces control but don't want to touch SIP. Because every action is a plain shell command, it suits people who already drive their Mac from skhd, Raycast, Alfred, Karabiner, Hammerspoon, or BetterTouchTool and want a single CLI they can bind to any of those tools. It's explicitly early-stage software — the project itself warns that "config keys, CLI flags and behaviour may still change between releases" — so it fits users comfortable tracking a fast-moving tool rather than those who need a stable, finished product.

How It Works

mimi's actions work standalone, without the daemon: space navigation, moving windows across spaces and displays, resizing to presets like halves, thirds, and quadrants, directional window focus, and closing, minimizing, or fullscreening a window are all plain CLI calls, and query commands return the desktop's state — spaces, windows, displays — as JSON. Running the background daemon unlocks the rest: hooks that fire shell commands on app, window, and space events; colored border outlines around focused versus unfocused windows; a menu bar indicator showing the active space and config reload status; and optional auto-tiling driven by a layout program you write yourself — mimi ships no built-in layout, and instead runs your program whenever windows change, passing it the windows as JSON on stdin and applying whatever frames it prints to stdout. Under the hood, mimi uses Objective-C bridges inside its Go codebase — space switching goes through synthetic dock swipes via CGEvent, moving windows between spaces uses private SkyLight APIs, and everything else runs on the public Accessibility framework, which is why it needs only Accessibility permission and no SIP changes.

Configuration

Configuration lives in a single TOML file. Hooks, for example, can filter by application, bundle ID, window title, or space number:

# ~/.config/mimi/config.toml
[hooks]
  { run = "command-here", space = 2 },
]

A tiling layout is just an executable referenced from config — mimi doesn't care what language it's written in, only that it reads the current windows as JSON from stdin and writes back frames on stdout. Six example layouts — monocle, columns, master-stack, a BSP-style dwindle, a stacked arrangement, and a scrollable strip — ship as starting points written in Python (chosen only because macOS bundles python3 with its JSON parser via Xcode's Command Line Tools), but a layout can just as easily be Lua, a compiled Rust or Go binary, or a bash script piped through jq.

Compared to Alternatives

Compared to yabai, which needs a partial SIP disable for some of its window-management features, mimi is built to leave SIP untouched entirely, trading some of yabai's deeper window-layer control for a simpler permissions story. Compared to AeroSpace, which replaces macOS Spaces with its own virtual workspace system, mimi works within native Spaces and switches between them using synthetic dock swipes rather than bypassing them. mimi's tiling is also pluggable rather than fixed — a layout is any user-supplied executable that speaks JSON over stdin/stdout, instead of a single built-in algorithm.

Requirements

  • macOS 14 Sonoma or later (the project pins a macOS 14.0 floor)
  • Accessibility permission required; no SIP modifications needed
  • Apple Silicon and Intel prebuilt binaries available, or build from source with Go and Xcode Command Line Tools
  • Early development — config keys, CLI flags, and behavior may still change between releases

Getting Started

Install with Homebrew: brew tap y3owk1n/tap then brew install --cask y3owk1n/tap/mimi (a Nix flake and prebuilt binaries are also available). Configuration lives at ~/.config/mimi/config.toml, created by mimi config init. From there, bind CLI calls like mimi action space 2 or mimi action focus_window --left to your hotkey tool of choice, and start the daemon to enable hooks, borders, and tiling. If you use a coding agent like Claude Code, Codex, or Cursor, the repo ships three skills — mimi-ask, mimi-setup-config, and mimi-setup-layout — installable via npx skills add y3owk1n/mimi, which can answer questions, write your config, and scaffold a tiling layout for you. See the GitHub repo for full CLI and configuration reference.

Discussion