miri logo

miri

Niri-ish, keyboard-first window manager for macOS.

MacosNiriPaperScrollWmSwiftMIT 189 8Health 68
github maria  rcks/miriko  fi maria__rcks
GitHub

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

Niri-inspired virtual workspace and column layout
Keyboard-first window management with extensive hotkeys
Accessibility API based window tiling (no compositor)
Configurable column width, animations, and trackpad navigation
Persistent layout and state across restarts
Hot-reload of config changes
Graphical menu bar status item with controls
Supports app-specific rules (float, ignore, width overrides)
Parks off-workspace windows with optional SkyLight alpha hiding
Restores tiled windows on exit and crash recovery
Supports three-finger trackpad swipe navigation via private MultitouchSupport
Customizable keybindings with modifiers and overrides

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.

Loading documentation…
View on GitHub

Featured in Videos

YouTube tutorials and walkthroughs for miri

Alternatives

Similar projects ranked by category, topics, and text overlap.

Compare
miri | MushyBook