window.ipc.postMessage() and Node receives the bytes through webview.onIpcMessage(). The second is the higher-level webview.expose() bridge, which lets you declare a namespace of values and async functions on the page’s global scope and call them like ordinary JavaScript. Both mechanisms run on the same thread without an HTTP server.
Sending messages from the page
wry automatically injects window.ipc.postMessage() into every page. Register your Node-side handler with webview.onIpcMessage(), then trigger postMessage from any page-side event.
message.body is a Buffer. Call .toString('utf8') (or another encoding) to read it as a string.
Custom IPC channel name
By default the only global available iswindow.ipc. Pass ipcName when creating the webview to add an alias for your own namespace. Both names call the same handler.
window.bindings.postMessage(...) or window.ipc.postMessage(...) interchangeably.
Sending data from Node to page
UseevaluateScript() for one-way updates — DOM manipulation, setting a title, or injecting data.
evaluateScriptWithCallback() when you need the evaluated result back in Node. The callback receives a serialized string result (or an error).
JSON messages
IPC message bodies are raw bytes. Using JSON is a practical convention for structured data without building a custom binary protocol.The expose() bridge
webview.expose(name, target) is the higher-level alternative to raw IPC. It registers a namespace on window in the page. Static JSON-serializable values appear directly on the namespace; async functions are wrapped so that every call from the page returns a Promise.
Node side — expose a namespace with static values and async functions:
await functions:
expose() rules and limits
What you can expose:- JSON-serializable scalar values: strings, numbers, booleans,
null, plain objects, arrays asyncfunctions (or functions that return aPromise)
Namespace uniqueness: Each namespace name can only be exposed once per
Webview instance. Calling expose() with a name that is already registered throws immediately.
When serialization fails — for example because you return
undefined from an
exposed function or pass a BigInt as an argument — WebviewJS throws a
SerializationError. Catch it in your async function or handle it in a
.catch() on the Promise returned by the page.Related pages
- Custom Protocols — serve local files over
app://(required for IPC on Windows) - Webview API reference — full method signatures for
onIpcMessage,evaluateScript,evaluateScriptWithCallback, andexpose