NatUI
Internals

Architecture

Understand the NatUI reconciler, bridge, native hosts, controlled state, and runtime paths.

┌────────────────────────── JavaScript process ──────────────────────┐
│ React application                                                  │
│       ↓                                                            │
│ react-reconciler 0.33 with a JavaScript shadow tree                │
│       ↓ atomic NDJSON commit                 ↑ native events       │
│ transport and Bridge                                               │
└───────┼──────────────────────────────────────┼──────────────────────┘
        ↓                                      │
┌────────────────────────── native host ───────┴─────────────────────┐
│ macOS: Swift and SwiftUI        │ Windows: C# and WinUI 3          │
│ observable node store           │ node registry and control map    │
│ recursive native view mapping   │ native controls and Grid layout  │
└─────────────────────────────────┴──────────────────────────────────┘

Native layout owns geometry

NatUI maps the React tree to platform declarative primitives. VStack becomes a SwiftUI VStack on macOS and a vertical native grid stack on Windows. The native toolkit owns layout proposals, focus, accessibility, theming, and control behavior.

There is no Yoga or browser layout layer. The tradeoff is intentional: applications get platform-native behavior rather than pixel-identical cross-platform rendering or CSS-style layout.

React reconciler

packages/natui uses react-reconciler mutation mode with a JavaScript shadow tree. Each instance records its id, kind, props, handlers, children, and materialization state.

Render-phase methods only construct or rearrange the shadow tree. Protocol operations are emitted during commit work after a node attaches to a materialized parent.

All operations from one React commit are buffered and sent as one commit message. A host applies the complete batch on its UI thread before one render pass, so it never displays an intermediate commit state.

React may discard render-phase instances. Deferring protocol creation until attachment prevents abandoned nodes from leaking into the native tree.

Props and handlers

Event-handler functions remain in a JavaScript registry. The host emits an event with the node id and event name, then the bridge locates and invokes the current handler.

Other props are validated and deep-copied into documented JSON values before serialization. Invalid nested values are reported with their component kind and path. A commit is all-or-nothing, so serialization failure cannot partially mutate the native tree.

Controlled inputs

Native controls apply edits optimistically for immediate feedback. Each edit carries a per-node sequence number. JavaScript acknowledges the highest processed sequence on its next update.

An acknowledgement older than the host's current sequence cannot overwrite the latest local value. When the acknowledgement catches up, React becomes authoritative again, including for transformations and rejected edits.

Events run at React's discrete priority and flush synchronously. After each controlled change, the bridge checks whether React adopted the value. If not, it sends a corrective update carrying the event acknowledgement.

See controlled state and the wire protocol.

Native hosts

macOS

The Swift host stores each node in an observable model. A recursive SwiftUI view switches on the node kind without type erasure, and children use stable ids so React moves remain native moves.

The host is a Swift Package Manager executable with native GUI application identity. It supports the Node standard-stream mode and an embedded JavaScriptCore mode.

Windows

The Windows host is an unpackaged, self-contained WinUI 3 executable. It uses a node registry and native control map. Grid-based stacks provide the flexible tracks needed by Spacer and infinite frames.

WinUI also raises events for programmatic changes, so prop application uses guards and structural equality checks to prevent feedback loops.

The base component set has real-window Node-mode verification. The newer app-shell set is currently compile-checked on Windows.

Debug surface

The protocol includes four verification messages:

  • dump returns the host's actual native node tree.
  • emit synthesizes an interaction event.
  • edit performs a real optimistic controlled edit.
  • screenshot renders the native window to a PNG and always receives success or error.

These messages allow end-to-end assertions without general-purpose UI automation. Popup layers and some focus or accessibility behavior still need dedicated native testing.

Runtime and packaging paths

The implementation is staged:

  • Stage 0, current development mode: React runs in Node, spawns the native host, and exchanges NDJSON over standard streams. This provides the current watch-and-remount development loop without application packaging.
  • Stage 1, researched sidecar packaging: A future native application could invert control and spawn a compiled JavaScript sidecar made with Bun or Node Single Executable Applications. The native application would own the sidecar lifetime. This is not implemented.
  • Stage 2, in-process execution: The macOS host can evaluate an esbuild browser bundle inside system JavaScriptCore. React's scheduler uses host-provided timer and microtask support. The bundle and host exchange protocol messages through __natui_send and __natui_recv, while standard input remains available as a verification debug channel.

The Windows in-process direction is Microsoft.JavaScript.Hermes, matching the engine family used by React Native Windows. It is researched but not implemented. NatUI does not yet ship the Stage 1 application wrapper, a packaging CLI, signing, or installer generation.

Current alpha boundaries

The repository includes 37 host components, including menus, toolbars, navigation, data views, and presentation. Menus are not out of scope.

Features still outside the current alpha scope include:

  • State-preserving React refresh
  • A public animation or gesture API
  • Multi-window application APIs
  • A packaging CLI or natui doctor command
  • Windows embedded execution

Accessibility labels, hints, identifiers, and the native controls' default accessibility behavior are in scope.

On this page