Electroview
Electroview is the browser-side SDK. Its primary job is to attach a typed RPC
object to the webview’s encrypted loopback transport, with a native bridge as
fallback.
Define A Shared Schema
An RPC schema has a bun side and a webview side. Requests have a typed
parameter and response; messages are one-way payloads.
import type { RPCSchema } from "electrobun/view";
export type AppRPC = { bun: RPCSchema<{ requests: { add: { params: { a: number; b: number }; response: { sum: number }; }; }; messages: { rendererReady: { title: string }; }; }>; webview: RPCSchema<{ requests: { getDocumentTitle: { params: {}; response: string; }; }; messages: { showStatus: { message: string }; }; }>;};Keep the schema in a module imported by both contexts. It contains types only and emits no runtime code.
Browser Side
Use Electroview.defineRPC() to provide handlers for the webview side, then
pass the returned object to the constructor. Calls can use the local rpc
variable immediately after construction.
import { Electroview, type RPCSchema } from "electrobun/view";
type AppRPC = { bun: RPCSchema<{ requests: { add: { params: { a: number; b: number }; response: { sum: number } }; }; messages: { rendererReady: { title: string } }; }>; webview: RPCSchema<{ requests: { getDocumentTitle: { params: {}; response: string }; }; messages: { showStatus: { message: string } }; }>;};
const rpc = Electroview.defineRPC<AppRPC>({ maxRequestTime: 10_000, handlers: { requests: { getDocumentTitle: () => document.title, }, messages: { showStatus: ({ message }) => console.log(message), }, },});
const view = new Electroview({ rpc });
const result = await rpc.request.add( { a: 9, b: 8 }, { maxRequestTime: 5_000 },);rpc.send.rendererReady({ title: document.title });
console.log(result.sum);void view;maxRequestTime on defineRPC is the default request timeout in
milliseconds. The optional second argument to one request overrides it;
Infinity disables the timeout for that call.
Main-Process Side
The same schema is attached to a BrowserView or BrowserWindow with
BrowserView.defineRPC():
import { BrowserView, BrowserWindow, type RPCSchema,} from "electrobun/main";
type AppRPC = { bun: RPCSchema<{ requests: { add: { params: { a: number; b: number }; response: { sum: number } }; }; messages: { rendererReady: { title: string } }; }>; webview: RPCSchema<{ requests: { getDocumentTitle: { params: {}; response: string }; }; messages: { showStatus: { message: string } }; }>;};
const rpc = BrowserView.defineRPC<AppRPC>({ handlers: { requests: { add: ({ a, b }) => ({ sum: a + b }), }, messages: { rendererReady: ({ title }) => console.log("Ready", title), }, },});
const win = new BrowserWindow({ title: "Typed RPC", url: "views://main/index.html", rpc,});
const title = await rpc.request.getDocumentTitle({});rpc.send.showStatus({ message: `Loaded ${title}` });void win;The directions are deliberate:
bun.requestsexecute in the main process and are called by the webview.bun.messagesare received in the main process and sent by the webview.webview.requestsexecute in the browser and are called by the main process.webview.messagesare received in the browser and sent by the main process.
Empty RPC
The constructor still requires an RPC object when the view has no application messages:
import { Electroview, type RPCSchema } from "electrobun/view";
type EmptyRPC = { bun: RPCSchema<{ requests: {}; messages: {} }>; webview: RPCSchema<{ requests: {}; messages: {} }>;};
const rpc = Electroview.defineRPC<EmptyRPC>({ handlers: { requests: {}, messages: {} },});
new Electroview({ rpc });Importing the view SDK is not required merely to use preload-provided custom
elements or draggable regions. Construct Electroview when the page needs the
application RPC transport.
Carrot Invocation
view.carrots.invoke() sends a request through the configured host RPC. It is
available only when the packaged host exposes the Carrot invocation handler.
import { Electroview, type RPCSchema } from "electrobun/view";
type EmptyRPC = { bun: RPCSchema<{ requests: {}; messages: {} }>; webview: RPCSchema<{ requests: {}; messages: {} }>;};
const rpc = Electroview.defineRPC<EmptyRPC>({ handlers: { requests: {}, messages: {} },});const view = new Electroview({ rpc });
const result = await view.carrots.invoke<{ value: string }>( "com.example.settings", "read", { key: "theme" },);console.log(result.value);Electrobun intentionally has no implicit browser-to-browser RPC. Route communication through the main process or use an explicit web transport.