Platform support
Check the target OS, the architecture, and the terminal features an application needs before you distribute it.
Supported targets
| Platform | Architectures | Current boundary |
|---|---|---|
| macOS | x64, arm64 | macOS 13.0 or later |
| Linux | x64, arm64 | glibc 2.17 or later |
| Windows | x64, arm64 | Desktop terminal applications |
| Android, iOS, web | — | Not supported |
Run the packaged health check on the machine that will run the application:
dart run noir:health_checkThe command verifies native-asset resolution and a headless buffer and render lifecycle. It does not open a real terminal, read raw input, or prove escape rendering.
On macOS, Dart 3.10 native-asset hooks can build with a macOS 12 target even though Noir’s bundled OpenTUI libraries require macOS 13. A build can therefore succeed on macOS 12 and fail later, when the native library loads.
Capabilities the terminal decides
Some output crosses a protocol negotiated with the reader’s terminal or multiplexer. Noir can generate or request the behavior; the receiving terminal still decides whether it works.
| Feature | Noir behavior | External dependency |
|---|---|---|
| Terminal images | Chooses Kitty, Sixel, or block fallback through ImageProtocol.auto | Terminal and multiplexer protocol support |
| OSC52 clipboard | Emits copy requests for explicit document selection | Terminal, tmux, or Screen acceptance and policy |
| Enhanced keyboard input | Can request Kitty keyboard reporting | Terminal support and encoding |
| Mouse input | Enables reporting when runTuiApp requests it | Terminal reporting and a real input session |
| Color and links | Records 24-bit color and semantic hyperlinks | Terminal rendering support |
Headless tests and Noir Driver are useful for layout, painted cells, cursor state, and parsed input. They cannot replace a check in the terminal you target.
Mouse pointer shapes
Noir can request desktop mouse shapes with OSC 22. This is
separate from the text caret. See Handle input and focus
for the widget behavior and custom MouseCursor regions.
Noir uses the modern OSC 22 shape stack where supported. Disabling mouse
reporting or disposing the app restores the previous stack entry. For iTerm2,
identified by TERM_PROGRAM=iTerm.app, Noir uses its legacy shape names and
resets to the terminal’s default pointer instead; that protocol cannot restore
a previously requested custom shape.
Unsupported terminals keep their own pointer appearance. Terminal and multiplexer support varies; emitting a request does not prove that the desktop pointer changed. Validate hover, clicks, and cleanup in the terminal you plan to use. Headless captures cannot show the desktop pointer.
Known limits, and what to do about them
- Leading zero-width text
A text run that begins with a zero-width grapheme can differ between Noir’s source-correct layout and the pinned native paint path. Do not isolate a leading zero-width grapheme into its own styled run.
- Border clipping
A decorated box that straddles a clipped viewport edge can paint its full border outside the native scissor rectangle. Keep bordered regions inside the viewport when exact clipping matters.
- macOS terminal teardown
On an observed macOS/iTerm path, alternate-screen teardown can return to main-screen row 1, column 1 and overwrite prior shell rows. Always dispose
TuiAppto release owned resources and terminal modes. The cursor-restoration limitation remains after disposal.- Linux native-library metadata
The official Linux libraries retain absolute build and debug paths from OpenTUI’s release environment. They are upstream artifact metadata, not paths produced on the application’s machine. No action is needed.
- Fractional opacity on ordinary text
The pinned native text fast path does not apply opacity values between
0.0and1.0; ordinary text paints as fully opaque, and0.0stays transparent. Express de-emphasis with a dimmer color instead. Alpha blending is available on supported cell and rectangle paint paths.- Forced Kitty graphics through tmux
This combination is unsupported, because initial image placement can overlap existing content until a resize. Use
ImageProtocol.autounder tmux; it selects block rendering.- Hot reload
Reload does not rerun
main()orinitState(). Live stack signatures, enum-to-class changes, reordered hooks, and native library changes need a full restart. See the development runner.- Drive mode
NOIR_DRIVE=1is headless. It is not evidence of raw-mode or terminal-protocol behavior. Treat a captured frame as proof of layout and painted cells only.- Native error detail
Some low-level native failures cannot be reported precisely to Dart. Keep application recovery at the supported widget or hosting boundary where possible.
The pinned OpenTUI source and the bundled native libraries are framework-owned. An application should not rebuild, replace, or patch those artifacts.
For dependency problems rather than platform problems, see Installation.