What is it?
What it is
A keyboard‑first window manager for macOS that emulates a Niri‑style virtual layout of workspaces and columns using public Accessibility APIs instead of a compositor.
Why it exists
To give macOS users a lightweight, tiling‑style window management experience that is keyboard‑centric, configurable, and does not rely on macOS Spaces or a custom compositor.
Who should use it
macOS power users, developers, and window‑manager enthusiasts looking for a keyboard‑first, tiling experience similar to Niri on Linux.
Who should avoid it
Users who rely on macOS Spaces, prefer native macOS window management, or are new to command‑line tools and Swift development.
How it works
A quick walkthrough in plain English
How miri works
Step 1 of 3
You interact with it
Open miri, send a request, or connect it to your stack.
Features
Advantages
- No need for a compositor; lower resource usage
- Works on macOS 13+ with Swift 6, no external dependencies
- Highly configurable via JSON, hot-reload
- Keyboard-centric, efficient workflow
- Persistence of layout and window positions
- Minimal permissions: only Accessibility and optional Input Monitoring
- Open-source MIT license
- Supports custom rules for specific apps
- Transparent to existing macOS features (Spaces not used)
- Easy installation via Swift package
Disadvantages
- Requires Accessibility permission and possibly Input Monitoring
- Uses private APIs (SkyLight, MultitouchSupport) which may break on OS updates
- Limited to macOS 13+; not available on older macOS versions
- No native integration with macOS Spaces or Mission Control
- May conflict with other window managers or automation tools
- Requires manual installation or building from source
- Performance overhead from Accessibility polling
- No support for GPU compositing; may not handle complex window effects
- Limited documentation for advanced configuration
- Potential security concerns with Accessibility permissions
Installation
FAQ
How do I install and run miri from source?
Clone the repository, navigate into the directory, and run `swift run miri`. For a release build use `swift build -c release` then execute `.build/release/miri`. You can also build a macOS disk image with `scripts/package-macos.sh --version 0.1.0` and open the resulting DMG.
What macOS permissions does miri require and when are they prompted?
miri needs Accessibility permission to control windows and may also need Input Monitoring for the event tap. When launched from a terminal, macOS will prompt the terminal app to grant these permissions the first time miri runs.
How are workspaces and columns navigated via keyboard shortcuts?
Use `Cmd+1`..`Cmd+9` to focus a workspace by index, `Cmd+0` for the previous workspace, `Cmd+J`/`Cmd+K` to move workspace down/up, `Cmd+H`/`Cmd+L` to focus column left/right, and `Cmd+[`/`Cmd+]` for first/last column. Modifiers with Shift move columns, with Ctrl adjust widths, and three‑finger trackpad swipes navigate columns/workspaces.
Where does miri look for its configuration file and how are changes applied?
miri checks (in order) the `MIRI_CONFIG` environment variable, `./miri.config.json`, `$XDG_CONFIG_HOME/miri/config.json` (if set), and finally `~/.config/miri/config.json`. The loaded file is watched for changes; saving valid JSON reloads keybindings, rules, layout settings, animations, and trackpad settings instantly, while invalid saves keep the previous config.
What happens to window layouts when miri is restarted or crashes?
With `persist_layout` enabled (default), miri writes a snapshot of workspace order, column order, manual widths, and focused window to `$XDG_STATE_HOME/miri/layout.json` or `~/.local/state/miri/layout.json`. On normal exit it restores tiled windows, and a small cleanup watcher attempts recovery after a crash or kill.
Featured in Videos
YouTube tutorials and walkthroughs for miri
Alternatives
Similar projects ranked by category, topics, and text overlap.