NativeWindow
API reference for the native window addon
NativeWindow Class
The NativeWindow class creates a native OS window with an embedded webview. It wraps the Rust napi-rs addon and manages the lifecycle automatically:
- Auto-init — the native subsystem initializes on first window creation
- Auto-pump — events are pumped at ~60fps (16ms interval) automatically
- Auto-stop — the event pump stops when all windows are closed
import { NativeWindow } from "@fcannizzaro/native-window";
const win = new NativeWindow({
title: "My App",
width: 1024,
height: 768,
devtools: true,
});Properties
id (readonly)
Unique numeric identifier for the window, assigned at construction time.
const win = new NativeWindow({ title: "My App" });
console.log(win.id); // e.g. 1WindowOptions
All options are optional. Pass them to the NativeWindow constructor:
| Option | Type | Default | Description |
|---|---|---|---|
title | string | "" | Window title |
width | number | 800 | Inner width in logical pixels |
height | number | 600 | Inner height in logical pixels |
x | number | — | X position in screen coordinates |
y | number | — | Y position in screen coordinates |
minWidth | number | — | Minimum inner width |
minHeight | number | — | Minimum inner height |
maxWidth | number | — | Maximum inner width |
maxHeight | number | — | Maximum inner height |
resizable | boolean | true | Allow window resizing |
decorations | boolean | true | Show title bar and borders |
transparent | boolean | false | Transparent window background |
alwaysOnTop | boolean | false | Float above other windows |
visible | boolean | true | Show window immediately on creation |
devtools | boolean | false | Enable browser devtools |
Content Loading
loadUrl(url: string): void
Navigate the webview to a URL.
win.loadUrl("https://example.com");loadHtml(html: string): void
Load an HTML string directly into the webview.
win.loadHtml("<h1>Hello</h1>");Security: Never interpolate unsanitized user input into HTML strings. Use a sanitization library such as DOMPurify or sanitize-html. See the Security guide for details.
unsafe.evaluateJs(script: string): void
Execute JavaScript in the webview context. This is fire-and-forget — there is no return value. Use postMessage/onMessage to send results back.
Grouped under the unsafe namespace to signal injection risk.
win.unsafe.evaluateJs('document.title = "Updated"');Security: Never pass unsanitized user input directly. Use
sanitizeForJs()to escape strings. See the Security guide for details.
postMessage(message: string): void
Send a string message to the webview. The message is delivered via the window.__native_message__ callback on the webview side.
win.postMessage("data from host");Window Control
| Method | Description |
|---|---|
setTitle(title: string) | Set the window title |
setSize(width: number, height: number) | Set the window size in logical pixels |
setMinSize(width: number, height: number) | Set minimum window size |
setMaxSize(width: number, height: number) | Set maximum window size |
setPosition(x: number, y: number) | Set window position in screen coordinates |
setResizable(resizable: boolean) | Enable or disable window resizing |
setDecorations(decorations: boolean) | Show or hide title bar and borders |
setAlwaysOnTop(alwaysOnTop: boolean) | Toggle always-on-top mode |
Window State
| Method | Description |
|---|---|
show() | Show the window |
hide() | Hide the window |
close() | Close and destroy the window |
focus() | Bring the window to focus |
maximize() | Maximize the window |
minimize() | Minimize the window |
unmaximize() | Restore the window from maximized state |
reload() | Reload the current page in the webview |
Events
| Method | Callback Signature |
|---|---|
onMessage(cb) | (message: string, sourceUrl: string) => void |
onClose(cb) | () => void |
onResize(cb) | (width: number, height: number) => void |
onMove(cb) | (x: number, y: number) => void |
onFocus(cb) | () => void |
onBlur(cb) | () => void |
onPageLoad(cb) | (event: "started" | "finished", url: string) => void |
onTitleChanged(cb) | (title: string) => void |
onReload(cb) | () => void |
Example:
win.onPageLoad((event, url) => {
if (event === "finished") {
console.log("Page loaded:", url);
}
});
win.onResize((width, height) => {
console.log(`Window resized to ${width}x${height}`);
});Utility Functions
sanitizeForJs
Escape a string for safe embedding inside a JavaScript string literal. Handles backslashes, quotes, newlines, null bytes, closing </script> tags, and Unicode line/paragraph separators.
import { NativeWindow, sanitizeForJs } from "@fcannizzaro/native-window";
const userInput = 'He said "hello"\n<script>alert(1)</script>';
win.unsafe.evaluateJs(`display("${sanitizeForJs(userInput)}")`);checkRuntime(): RuntimeInfo
Check if the native webview runtime is available. Returns { available: boolean, version?: string, platform: "macos" | "windows" | "unsupported" }.
ensureRuntime(): RuntimeInfo
Check for the runtime and install it if missing (Windows only). Downloads the WebView2 Evergreen Bootstrapper (~2MB) from Microsoft and runs it silently. Throws on failure.
RuntimeInfo
Return type for checkRuntime() and ensureRuntime():
interface RuntimeInfo {
available: boolean;
version?: string;
platform: "macos" | "windows" | "unsupported";
}Legacy API
The following functions exist for backward compatibility but are not needed when using the NativeWindow class, which manages initialization and event pumping automatically:
| Function | Description |
|---|---|
init() | Initialize the native window system manually |
pumpEvents() | Process pending native UI events manually |
run(intervalMs?) | Convenience: calls init() then starts a pumpEvents() interval. Returns a cleanup function. Deprecated. |
Known Limitations
- ~16ms event latency from the
pumpEvents()polling interval - HTML null origin — content loaded via
loadHtml()has a null CORS origin; useloadUrl()for fetch/XHR - No return values from
unsafe.evaluateJs()— usepostMessage/onMessageto send results back - 2 MB HTML limit on Windows when using
loadHtml() - Use
bun --watchinstead ofbun --hotfor development (native addon reloading requires a process restart)