> ## Documentation Index
> Fetch the complete documentation index at: https://webview.js.org/llms.txt
> Use this file to discover all available pages before exploring further.

# WebviewJS: Cross-Platform Native Webview for Node.js

> WebviewJS is a Rust-powered native webview library for Node.js, Deno, and Bun. Build desktop apps with real OS windows, menus, tray icons, and IPC.

WebviewJS (`@webviewjs/webview`) is a native binding to [tao](https://github.com/tauri-apps/tao) and [wry](https://github.com/tauri-apps/wry) — the same battle-tested Rust GUI primitives that power Tauri — exposed directly to Node.js, Deno, and Bun through a zero-overhead NAPI-RS bridge. You get real OS windows, a system webview, menus, tray icons, IPC, custom protocols, and desktop notifications without shipping a bundled browser or adopting a full application framework.

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/quickstart">
    Create your first native window in under five minutes.
  </Card>

  <Card title="IPC Messaging" icon="arrows-left-right" href="/guides/ipc-messaging">
    Send messages between the page and Node.js in both directions.
  </Card>

  <Card title="API Reference" icon="cube" href="/api/application">
    Full reference for Application, BrowserWindow, Webview, and more.
  </Card>

  <Card title="Build Executables" icon="box" href="/guides/building-executables">
    Compile your app into a single self-contained binary.
  </Card>
</CardGroup>

## What you can build

WebviewJS gives you direct access to OS-level GUI primitives from JavaScript:

* **Desktop windows** — create, resize, move, and style native OS windows with full decoration control
* **Embedded webviews** — render any URL or inline HTML inside a native window using the OS's own WebKit/WebView2 engine
* **Promise-based readiness** — `app.whenReady()` resolves after the first native `Resumed` event, giving you a clean async entry point for window creation
* **Non-blocking event pump** — `app.run()` drives the GUI via `setInterval` so all of Node's async I/O, timers, and network continue to work normally alongside the GUI
* **Bidirectional IPC** — send typed messages from the page to Node via `window.ipc.postMessage()` and call back with `webview.evaluateScript()`
* **Exposed function namespaces** — publish async Node.js functions to the page with `webview.expose()`, callable as `await window.myNS.myFn()`
* **Custom protocols** — serve local files or handle `app://` requests with a Fetch-compatible handler, including full Hono routing without an HTTP server
* **Native menus** — build cross-platform menu bars with keyboard accelerators, roles, and per-window menus
* **System tray icons** — create tray icons with menus, tooltips, and pointer event listeners
* **Desktop notifications** — show native OS notifications with a browser-familiar API; permission is always `"granted"` for native apps
* **Shared browser contexts** — isolate cookies, caches, and storage across webviews using `WebContext` profiles
* **DevTools access** — open or close the browser DevTools panel programmatically
* **CLI build tool** — the `webview` CLI compiles your app to a self-contained single-file executable targeting Node.js, Deno, or Bun

## Supported runtimes

| Runtime | Minimum version | Notes                                                          |
| ------- | --------------- | -------------------------------------------------------------- |
| Node.js | 24.0.0          | Prebuilt `.node` binaries via NAPI-RS; no compilation required |
| Deno    | Latest stable   | Import from npm using `npm:@webviewjs/webview`                 |
| Bun     | Latest stable   | Drop-in compatible; no extra configuration needed              |

Prebuilt native binaries are published for every supported platform — `npm install` downloads the correct binary automatically. No Rust toolchain is required for normal use.

## Supported platforms

| Target triple                   | OS      | Arch                  | Status          |
| ------------------------------- | ------- | --------------------- | --------------- |
| `x86_64-pc-windows-msvc`        | Windows | x64                   | ✅ Supported     |
| `i686-pc-windows-msvc`          | Windows | x86                   | ✅ Supported     |
| `aarch64-pc-windows-msvc`       | Windows | arm64                 | ✅ Supported     |
| `x86_64-apple-darwin`           | macOS   | x64                   | ✅ Supported     |
| `aarch64-apple-darwin`          | macOS   | arm64 (Apple Silicon) | ✅ Supported     |
| `x86_64-unknown-linux-gnu`      | Linux   | x64                   | ✅ Supported     |
| `aarch64-unknown-linux-gnu`     | Linux   | arm64                 | ✅ Supported     |
| `armv7-unknown-linux-gnueabihf` | Linux   | armv7                 | ✅ Supported     |
| `i686-unknown-linux-gnu`        | Linux   | x86                   | ⚠️ No CI        |
| `aarch64-linux-android`         | Android | arm64                 | ⚠️ Experimental |
| `armv7-linux-androideabi`       | Android | armv7                 | ⚠️ Experimental |
| `x86_64-unknown-freebsd`        | FreeBSD | x64                   | ⚠️ No CI        |

## How it works

WebviewJS is a thin NAPI-RS binding. When your JavaScript calls `app.createBrowserWindow()`, the call crosses the JS/Rust boundary synchronously and creates a native window handle owned by the Rust runtime. The webview is embedded inside that window using wry, which delegates to the OS's own rendering engine — WebView2 on Windows, WebKit on macOS, and WebKitGTK on Linux.

The event loop bridges Node and the native GUI through a non-blocking `pump_events()` call that drains the OS message queue without blocking Node's event loop. `app.run()` sets up a `setInterval` at \~16 ms (configurable) that calls `pumpEvents()` on each tick. Because this runs inside a normal Node timer, all of Node's async I/O continues working exactly as usual alongside the GUI.

IPC crosses the JS/Rust boundary in the opposite direction: the page calls `window.ipc.postMessage()`, which routes through the native webview's script-message bridge into your Node handler.

<Note>
  WebviewJS is a lightweight system webview binding, not a full application framework. It does not bundle a browser engine, provide a build system, or abstract away the OS the way Electron or Tauri do. You get direct, low-level access to native windowing and webview primitives from JavaScript — what you build on top of that is entirely up to you.
</Note>
