docs/limitations.md

Known limitations

This page lists every known limitation of Miri in one place. Each entry names its kind, what triggers it, what you notice, any workaround, and the evidence behind it. Report a limitation that is missing here through GitHub Issues.

How to read this page

Unless an entry says otherwise, it applies to Miri Developer built from main at fabf16d4, with the engine pinned at 589b44b. Miri has no release, so no entry describes a released version. The audit for #91 checked each entry against the source and the evidence on 27 October 2026. Later the same day, the page was updated for main at 6882f8a, with engine 7b180e6, to drop the fixed #120 and the verified #72.

Each entry has one of five kinds:

  • Platform constraint. macOS, the hardware, or the bundled engine sets the limit, and Miri works within it.
  • Scope exclusion. Sam decided that v1 does not do this.
  • Not built yet. Accepted v1 work that is not finished. Its issue tracks the work.
  • Confirmed defect. Someone observed the wrong behavior on the real app.
  • Unverified. Someone reported or suspects the behavior, or a scenario has not run on hardware. An unverified entry is not an established limitation.

Previously undocumented marks a confirmed entry that no user documentation, decision record, or architecture decision mentioned before this audit. Working notes in PROGRESS.md and issue comments do not count as documentation.

Release and support

LimitationKindTrigger and impactWorkaroundEvidence and tracking
Miri has no release. You can only build it from source as Miri Developer. No Developer ID signed and notarized release disk image exists, and no Homebrew cask exists. make package builds a development disk image only.Not built yetAny use.Build from source as the README describes.Signing, distribution, and updates, scripts/build-app.sh, #82.
Miri does not update itself. The accepted Sparkle updater is not built yet.Not built yetAny use. You must rebuild to get changes.Pull main and run make build.No Sparkle code exists in Sources/. Design tree status, #82.
No v1 acceptance check has passed. No release candidate is frozen, and 0 of 3 full runs have passed.UnverifiedEvery behavior on this page and in the release scope still needs its recorded check.None.Acceptance ledger, #83.
Many recent fixes were checked with synthetic keyboard and mouse input only. Sam's hand checks of drag into another stack passed on 31 October 2026, and of the pointer drop target on 1 November 2026. A physical check is still open for stack overflow and the stack limit.UnverifiedReal input can differ from synthetic events.None.#43, closed, #203, closed, checks S-5 to S-7 in the acceptance ledger.

Platforms and hardware

LimitationKindTrigger and impactWorkaroundEvidence and tracking
Miri runs only on Apple silicon Macs with macOS 15.0 or later. Intel Macs and older macOS versions are not supported.Scope exclusionThe build script stops on a Mac that is not arm64, and the app declares macOS 15.0 as its minimum.None.Supported platforms, scripts/build-app.sh.
On macOS 15, Miri has run only in a virtual machine. Trackpad gestures, multiple displays, display changes, and sleep and wake have not run there. Miri has not run on macOS 26 at all.UnverifiedAny use on macOS 15 or 26.None.#369 records the virtual machine checks, and #376 tracks the hardware checks.
Development has used one Mac, a MacBook Air with an Apple M3 chip, with at most two displays at once.UnverifiedOther Mac models and three or more displays have not run.None.Multiple monitors.
Strip gestures need a built-in trackpad or a Magic Trackpad.Platform constraintA Mac with only a mouse has no strip swipe.Use the keyboard commands, or a modifier with the mouse wheel.Setup.

Permissions and macOS settings

LimitationKindTrigger and impactWorkaroundEvidence and tracking
Miri needs Accessibility permission, and it will not start window management without it.Platform constraintPermission off. The setup checker shows a problem.Turn on Miri Developer in System Settings > Privacy & Security > Device Control and Data Access on macOS 27, or > Accessibility on macOS 15.System access, ADR 0002.
Miri refuses to start while Displays have separate Spaces is off. Changing that setting needs a log out.Platform constraintThe setting is off. Window management stays stopped.Turn the setting on, then log out and back in.Conflicts and setup checker, ADR 0008.
Miri blocks start for only four competing window managers: Paneru, AeroSpace, Amethyst, and yabai. It warns about only three window-snapping apps: Rectangle, Loop, and Magnet. Any other tool that moves windows runs beside Miri with no warning.UnverifiedAnother tool that moves windows runs beside Miri. Whether a given tool conflicts is not checked.Quit other tools that move windows before you start Miri.SetupChecker.swift, #277. Each bundle identifier was read from the installed app.
Stage Manager, the macOS tiling options, and window-snapping apps such as Rectangle, Loop, and Magnet move windows that Miri arranges. Miri warns about them but does not block.Platform constraintOne of them is on or running. Windows can leave their layout place.Turn them off, or quit the app. The setup checker links to each macOS setting.Conflicts and setup checker, #43, #277. verify-miri runs on 5 November 2026 moved a tiled window with each app: Rectangle 1.100 through Maximize (its URL action and Control-Option-Return) and through edge snapping, Loop 1.4.2 through its Maximize URL action and its Globe trigger key, and Magnet 3.0.7 through Control-Option-Return. Each time, Miri put the window back in its column within about 30 to 45 ms. In both Maximize tries on main at 6f398e2b, the column also swapped places with its neighbor. With Control-Option-H bound in both Rectangle and Miri, Miri's shortcut ran. In Sam's hand check (run 20261106-000259), Loop's Globe trigger resized a tiled window 14 times, and Miri put it back within 25 to 50 ms each time, too fast to see. Magnet's edge snapping showed its snap preview for Sam's own windows while Miri managed windows, but never for the test windows. When Sam dropped a tiled window on a Magnet snap area, Magnet placed it, and Miri then moved it back to its column. A drop that kept the window's size slid back in 0.4 to 0.6 s, which is Miri's normal drop animation with Animate window movement on, with or without a snapping app (runs 20261106-002521 and 20261106-122455). Before #314, a drop where Magnet changed the window's size took 0.5 to 7.5 s in 7 tries, and once Miri kept Magnet's width of 1280 points (run 20261106-122455). With the fix in paneru#134, run 20261107-010533 dropped a tiled T3 Code window and fired Magnet's own top-right quarter and right third shortcuts at the release: the window was back in its full column in 0.34 to 0.60 s in 4 of 4 drops. The engine before the fix kept Magnet's right third in the same drop. A snap by shortcut is undone at once, because Miri restores a tiled frame without animation.
Miri never changes macOS settings. When a known macOS gesture conflicts with a strip gesture, or Miri cannot read the gesture settings, the strip gesture stays off.Platform constraintA conflict, or no successful gesture test.Change the macOS gesture, then run Test Gesture. Keyboard commands work meanwhile.Strip gestures.
Settings can show Launch at login on while Miri will not start at login. Launch at login has not been checked with a log out and log in.Not built yet for showing the login item's state, unverified for a log out and log inmacOS holds the login item for approval, or the user turned it off in System Settings > General > Login Items. Settings shows neither state. Settings does not reflect changes made in macOS Login Items, including after Miri restarts. Miri registers the login item only when it runs from an Applications folder, and a first launch from anywhere else, such as the mounted disk image, registers nothing.Run Miri from an Applications folder. Settings says so when Miri runs from anywhere else.syncLoginItem in AppModel.swift, #201.

Displays

LimitationKindTrigger and impactWorkaroundEvidence and tracking
A thin sliver of each off-screen window stays visible at the display edge. On a side that touches another display, the window instead hangs past a bottom corner of its display that has no display beyond it, with 1 point of its width showing. When displays sit beyond both bottom corners, the whole width of the window shows as a thin bar at the bottom of that side.Platform constraint, previously undocumentedAny strip wider than its display. macOS moves windows that sit fully off-screen, so the engine keeps 5 points showing at a free edge.The engine keys sliver_width and sliver_height set the size at a free edge.The engine's recommended system options, #150.
On an edge that touches another display, a hidden window shows as a photo of its slice, not as the real window. While someone can see the edge, Miri takes a new photo every 2 seconds, so the photo can be up to about 2 seconds old. When a window crosses the edge again, Miri first shows the photo it kept from the last time, which can be older, until a new one arrives. The first time a column crosses after the engine starts, it moves at once if no photo is kept yet. Some apps, such as Notion, draw nothing while their window is hidden. Miri keeps such a window's last photo from when it showed, so the photo does not change while the window stays hidden. A window waits in view up to 1.5 seconds for its first photo before it hides, so its slice shows right after Miri starts. If no photo arrives in that time, the edge shows nothing for it until it crosses once. A click on the photo focuses the window and scrolls it into view. The click then reaches the app on the row you clicked, at least 12 points inside the window edge that the photo showed, so it misses the resize border. A drag that starts on the photo does the same, then goes on as a drag in the app. A drag that you release before the window arrives does not reach the app. A second click while the window slides in is dropped, so a fast double click acts as one click. When the window arrives, the pointer jumps to the point where the click reaches the app. If the window does not arrive within about 1.5 seconds, the click is dropped. The window stays focused and Miri keeps the scroll it started, but the window can stay off screen. Scrolling and hovering over the photo do nothing.Platform constraintDisplays side by side with Show window contents on edges next to another display on, which sets [options] shared_edge_slices. The switch is off by default, and it needs Screen Recording permission. With the switch off or without the permission, the edge shows nothing.To scroll the window, first click the photo or scroll its column into view.macOS moves a window that lies mostly on another display, and it does not send events to an off-screen window. The engine draws the photos in src/ecs/slice_photos.rs and src/slice_screen.rs, and handles the click in src/platform/slice_tap.rs and src/ecs/slice_input.rs. Checked on Sam's M3 with a real trackpad and keyboard on 29 and 30 October 2026. #150.
Mixed arrangements, which need three displays, have not run. Grid arrangements and a maximum display count are deferred to v2.Unverified for mixed, scope exclusion for gridsThree or more displays.None.Multiple monitors.
A window that is off screen while the screen is locked, such as one on a hidden native Space, may drop out of Miri. It stays open but is no longer tiled.UnverifiedA screen lock or a sleep and wake.Restart Miri, or focus the window.#210, #147.
A window that you drag in Mission Control onto another display's desktop does not move there. It stays in its old display's strip, and the Space does not change.Confirmed defectA Mission Control drag from the external display onto the built-in display. The keybinding reference names this drag as the way to move a window to another Space.None known.Sam's hardware test on 28 October 2026. A harness replay refused the move in the same way on engine 1fd95b1 and ade3f05. Which events macOS 27 sends for this drag is not yet known. #143.
With displays side by side and Show window contents on edges next to another display off, a column that scrolls off the edge they share slides only until about half of it has crossed, then vanishes.Platform constraintA column whose centre crosses onto the other display. On 3 November 2026 a 2552 point wide window slid for 2 or 3 frames and vanished with about 60% of it still in view.Turn the switch on. Then a photo of the window slides on past the edge.macOS moves a window that lies mostly on another display, so with no photo nothing can show past the midpoint. Before the fix, on main at c356ad7a, verify-miri run 20261103-112536 showed the column vanish on the first frame in 3 of 3 presses. With paneru#120, run 20261103-113541 showed it slide first in 3 of 3 presses, and run 20261105-173029 on the merged engine 4dc453f showed the same. #159.
While the row scrolls past an edge shared with another display, a slow app's window can leave the desktop showing beside the column ahead of it for about 100 ms. It happens when a press arrives while the slow window lands under its photo, or, with shared-edge photos off, while it leaves for its tuck. A fast window next to the shared edge can also go missing for a few frames, leaving up to 390 points of desktop, for a cause not yet found.Confirmed defect for the landing case and the missing edge window, unverified for the leaving caseScrolling the row with displays side by side and a slow app beside the edge. On 6 November 2026, main showed desktop beside a slow stand-in window in 2 of 7 rounds of presses, up to 176 points wide. A real Helium window did not show it in 24 rounds. The missing edge window showed about 110 ms of desktop in 24 rounds, with and without the pacing fix.None known.Sam's recording on 29 October 2026, with engine 591ddd9, showed the desktop between columns for 1 to 4 frames, up to about 370 points wide. #171, #174, and #175 fixed that gap, with engine e7742b8. Engine PR #128, with engine ee3e3b5, paces the column ahead of a leaving or landing window, and is not yet checked live. #163.
After you drag a display back in System Settings > Displays > Arrange, the System Settings window can still move into the other display's strip. It happened once in 18 drags back.Confirmed defectA drag in the Arrange sheet that moves the display holding the System Settings window. The window shows on the other display, in that display's strip. The cause is unknown.Focus the window, then press Control-Option-Command-Shift with the arrow key toward its display.One drag back in verify-miri run 20261102-234313 on 2 November 2026, on the logic of engine ecd584a. The other 35 drags, 18 to the right and 17 back, kept every strip, 26 of them on builds with trace lines (runs 20261102-234952 and 20261103-005228). #262 fixed the case that happened on every drag. Reopen it if this shows again. Sam accepted this case as a limitation when #103 closed on 3 November 2026.

Finding and restoring windows

LimitationKindTrigger and impactWorkaroundEvidence and tracking
After an engine restart, a maximized column may come back partly in view.UnverifiedRestart Engine, a crash restart, or relaunching Miri, with a maximized column in a row.Focus the window.The fix for #69 restores each row where it was scrolled, and live runs on 2 November 2026 with engines f5a3866 and a358a36 kept every window in place. Those runs had no maximized column.
Session restore drops windows that no longer exist and closes the gaps they leave. It keeps no state for a display that is not connected.Platform constraint, previously undocumentedRestart after windows close or a display disconnects.None.The engine's session restore documentation.
A window that matches a floating rule floats after a restart, even if it was tiled when the layout was saved. A window you tiled with the float toggle stays tiled.Scope exclusionRestart with a floating rule that matches a tiled window.Tile it again with Control-Option-T.Startup and crash recovery, #15, #93.
By default, the engine ignores windows that are neither standard nor floating windows, such as dialogs. It also ignores background apps that run without a Dock icon.Platform constraint, previously undocumentedThose windows stay where the app puts them.The engine documents a window rule with manage = true in config.toml that manages them. Settings has no control for it, and this rule has not run with Miri.The engine's window rules documentation.

Stacks and window sizes

LimitationKindTrigger and impactWorkaroundEvidence and tracking
When Finder is frontmost with no window, the previously focused stack window can stay above its overlapped place.Scope exclusionClick the desktop or close Finder's last window. The order returns when focus reaches a managed window.Focus any managed window.Stacks, #42.
An app that applies a new size more than 500 ms late can have its old height recorded as a minimum.Unverified, previously undocumentedSlow apps, such as some Chromium browsers. Inferred from the engine design and not observed.None known.#40, closed. Next step: stack a fixture window that applies each new size 1 second late, then check whether the engine records a false minimum height.
Fixed-size windows float automatically. A fixed-size window that you tile keeps its own size, so empty space shows beside or below it.Scope exclusionTile a fixed-size window with Control-Option-T.None.V1 interactions, Stacks, #93.
A window with a maximum size maximizes only to that size, at the top-left of the usable area.Platform constraintMaximize such a window.None.Maximizing a window.

Dragging, gestures, and focus

LimitationKindTrigger and impactWorkaroundEvidence and tracking
Swipe lag builds up over time.Confirmed defect, previously undocumentedLong sessions. The cause is unknown.Quit and reopen Miri.#66.
Trackpad scrolling cannot target the strip under the pointer, and no setting chooses between the strip under the pointer and the focused window's strip. V1 accepts the strip under the pointer as the default and a setting for the focused window's strip.Not built yetA swipe with two displays. From the engine code, a swipe moves the strip on the display whose menu bar is active. This has not been checked on hardware.None known.Multiple monitors, the v1 plan in PROGRESS.md, swipe_gesture in the engine's src/ecs/scroll.rs at 589b44b, check S-1 in the acceptance ledger, #212.
After focus goes to a display with no window and back to the same window, the engine can keep trusting a slow app to apply moves on time. If that app then applies its first move late, the window ahead can run off and show the desktop.UnverifiedFocus moves from a window to an empty display, where Finder comes to the front with only its desktop, then back to the same window. A probe log showed the mechanism on engine e7742b8, but nobody saw it on screen. On 31 October 2026, the gap did not show in 24 round trips, and Helium applied its moves on time each time.None known.#177.
The macOS system Picture-in-Picture window, which Safari, QuickTime Player, and IINA use, cannot take keyboard focus.Platform constraintPicture-in-Picture in those apps. macOS keeps the window above other windows.Use the window's controls with the pointer.V1 interactions, #77. Firefox and Zen Picture-in-Picture have not run.
In Chromium-based browsers, a double-click on a tab also maximizes the window.Platform constraintThe browser hides its tabs from Accessibility.Double-click the title bar away from the tabs.Maximizing a window.
A Picture-in-Picture window stays on the display where it opened. It does not follow focus to another display.Scope exclusionMove focus to another display while Picture-in-Picture plays.Move the window by dragging it.V1 interactions, #77.
Next to a display edge, only the gap between a stack's column and the edge lets a drag move a stacked window to a new column on that side.Scope exclusionOver its own column, a drop only reorders the stack, so the pointer must reach the few points between the column and the edge.Press ⌃⌥⇧] or ⌃⌥⇧[ to pop the window out to that side, or drop it on the near quarter of the column on the other side.Dragging windows, #203.
When a drop on another display scrolls that display's strip to show the window, the strip keeps that scroll after the window leaves again.Scope exclusionA window dropped from another display scrolls the strip to show itself and is then dragged away, which leaves the strip at that scroll even though the columns past it slide back. The strip never keeps empty space past an end, so this shows only when the window was not the strip's last column.Scroll the strip back with a swipe or a focus command.Dragging windows, #320.
A new window can stay off screen while its app shows a dialog that the engine ignores, such as an AXDialog window.UnverifiedThe app opens a new window and, at the same moment, reports such a dialog as its focused window. The engine drops its own focus of the new window, so the window stays parked until the dialog closes. Once the dialog closes and the app focuses the window, it takes focus and comes into view. No app is known to do this. LibreOffice's Tip of the Day is a floating window that the engine tracks, which #325 fixed.Close the dialog.An engine test on 69a2414 fails with the window parked while the dialog shows. samanyudas/paneru#133 adds the test that the window comes into view after the dialog closes. Recorded in #325.

Reports not yet reproduced

These reports are not established limitations. Each one has an open issue with the next investigation step.

  • Window interactions feel delayed: #78.

Deferred to v2

V1 leaves out the optional Miri dock, portable display layouts, tabbed columns, the minimap, inactive-window dimming, and advanced window rules. It also leaves out focus borders, a focus-follows-mouse control, display exclusions, fixed-pixel presets, animation tuning, Hyper-key recording, five-finger gestures, and the guided shortcut tutorial. A deferral does not commit Miri to building the feature in v2. Miri does not offer virtual workspaces, which are extra strips within one macOS Space. Use macOS Spaces instead, because each Space has its own strip. Release scope owns that list, and the v2 roadmap records the candidates.