NatUI
Guides

Runtime modes

Choose between the Node development process and an embedded JavaScript runtime.

Node process

The default development path runs React in Node. run locates and spawns the native host, then exchanges newline-delimited JSON over standard input and output.

import { run } from '@natui/core';

await run(<App />, { title: 'NatUI app' });

Use the natui dev command for the normal development loop:

{
  "scripts": {
    "dev": "natui dev",
    "start": "tsx src/main.tsx"
  }
}

The CLI reads entry from natui.app.json. A positional entry overrides the config, and src/main.tsx is the fallback when no config exists.

The server bundles and watches the application's local source graph. After a successful edit, React Fast Refresh updates the existing React root without restarting Node or the native host. Compatible function components keep hook state and native control identity. Build and evaluation errors keep the last working UI mounted.

The entry must call run() once. Startup options such as the host path, title, and initial window size apply to the first generation. Restart the server to change them. The server is an in-process module builder and watcher, so it does not listen on an HTTP port.

Embedded JavaScript

Both hosts can evaluate a browser-targeted bundle in-process. macOS uses system JavaScriptCore and Windows uses V8. runEmbedded resolves to a controller after the first React commit:

import { VStack, Text } from '@natui/core/components';
import { runEmbedded } from '@natui/core/inproc';

const app = await runEmbedded(
  <VStack padding={20}>
    <Text>Hello from embedded JavaScript</Text>
  </VStack>,
  { title: 'embedded app' },
);

app.update(
  <VStack padding={20}>
    <Text>Updated in place</Text>
  </VStack>,
);

Build and run the included embedded demo:

pnpm build:host:macos
pnpm build
pnpm --filter natui-demo build:embedded
hosts/macos/.build/release/natui-host --bundle examples/demo/dist/embedded.js

On Windows, build the WinUI host and launch the same bundle:

dotnet build hosts/windows/NatuiHost -c Release -p:Platform=x64
pnpm build
pnpm --filter natui-demo build:embedded
hosts\windows\NatuiHost\bin\x64\Release\net8.0-windows10.0.19041.0\win-x64\NatuiHost.exe --bundle examples\demo\dist\embedded.js

Component imports come from @natui/core/components so the bundle does not include Node built-ins. @natui/core/inproc exchanges the same protocol messages through host-injected functions rather than standard streams.

Embedded mode is implemented and locally verified on both platforms through the same lifecycle and bridge contract. app.quit() synchronously unmounts React, runs effect cleanup, sends one quit request, and detaches the receive hook. Repeated calls are safe.

Native application packaging

The repository also packages the embedded demo as a native application:

pnpm package:demo
pnpm verify:package

The configuration lives at examples/demo/natui.app.json. Its entry is the same src/main.tsx used by the development server. Packaging maps the normal @natui/core run() import to the embedded runtime, so one entry file serves both development and packaging.

macOS produces examples/demo/dist/package/NatUIDemo.app. Windows produces one portable, architecture-specific, self-contained EXE in the same output directory. The Windows EXE extracts its runtime dependencies to a per-user temporary cache when it launches.

Both artifacts contain a generated manifest and SHA-256 digest for the JavaScript entry. The loader checks bundle schema, protocol, minimum host API, platform, architecture, and entry integrity before evaluation.

See application bundles for the configuration, artifact layout, lifecycle, verification, and current release boundaries.

On this page