Documentation Index

Fetch the complete documentation index at: /llms.txt

Use this file to discover all available pages before exploring further.

Skip to main content
WebviewJS (@webviewjs/webview) is a native binding to tao and 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.

Quickstart

Create your first native window in under five minutes.

IPC Messaging

Send messages between the page and Node.js in both directions.

API Reference

Full reference for Application, BrowserWindow, Webview, and more.

Build Executables

Compile your app into a single self-contained binary.

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 readinessapp.whenReady() resolves after the first native Resumed event, giving you a clean async entry point for window creation
  • Non-blocking event pumpapp.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

RuntimeMinimum versionNotes
Node.js24.0.0Prebuilt .node binaries via NAPI-RS; no compilation required
DenoLatest stableImport from npm using npm:@webviewjs/webview
BunLatest stableDrop-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 tripleOSArchStatus
x86_64-pc-windows-msvcWindowsx64✅ Supported
i686-pc-windows-msvcWindowsx86✅ Supported
aarch64-pc-windows-msvcWindowsarm64✅ Supported
x86_64-apple-darwinmacOSx64✅ Supported
aarch64-apple-darwinmacOSarm64 (Apple Silicon)✅ Supported
x86_64-unknown-linux-gnuLinuxx64✅ Supported
aarch64-unknown-linux-gnuLinuxarm64✅ Supported
armv7-unknown-linux-gnueabihfLinuxarmv7✅ Supported
i686-unknown-linux-gnuLinuxx86⚠️ No CI
aarch64-linux-androidAndroidarm64⚠️ Experimental
armv7-linux-androideabiAndroidarmv7⚠️ Experimental
x86_64-unknown-freebsdFreeBSDx64⚠️ 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.
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.
Assistant
Responses are generated using AI and may contain mistakes.
Morty Proxy This is a proxified and sanitized view of the page, visit original site.