electron-wcap
v1.1.0
Published
Electron WebContent API Provider — call renderer APIs from the main process with support for passing callbacks.
Maintainers
Readme
electron-wcap
Electron WebContent API Provider — call renderer APIs from the main process with support for passing callbacks.
Overview
electron-wcap lets the main process use an API object that lives in a renderer (a WebContents). You get a typed proxy in the main process; calling a method runs the corresponding function in the renderer via injected script. Functions you pass as arguments are registered and bridged so the renderer can invoke them back into the main process.
- Main process: create a provider for a given
WebContentsand API key; use it like a normal async API. - Preload: expose the callback bridge so renderer code can invoke those callbacks.
- Renderer: assign your API object to
window[apiKey]and use it as usual.
Install
npm add electron-wcapRequires Electron (peer dependency). Node 22+ and pnpm are recommended (see volta in package.json).
Example
Usage
1. Main process
Import from electron-wcap/main and create a provider for a WebContents and a string apiKey that the renderer will use for the same API:
import { createApiProvider } from 'electron-wcap/main';
// e.g. after creating a BrowserWindow
const provider = createApiProvider<MyApi>(win.webContents, 'myApi');
function onData(data: unknown): void {
// This callback runs in the main process when the renderer calls it
console.log('Renderer sent:', data);
}
// Call renderer methods (return value is a Promise)
const result = await provider.someMethod('arg', onData);- The generic
MyApiis for typing only; the real implementation lives in the renderer. - Callbacks must be named functions (used as registry keys).
2. Preload
Import from electron-wcap/preload and enable the callback bridge so the renderer can invoke callbacks passed from main:
import { enableCallbacks } from 'electron-wcap/preload';
enableCallbacks();Load this script as the preload for any window whose renderer API you use with createApiProvider.
3. Renderer - optional
Expose your API on window under the same apiKey you used in createApiProvider:
const apiKey = 'myApi';
window[apiKey] = {
someMethod(arg: string, callback: (data: unknown) => void) {
// callback is a function that runs in the main process
callback({ received: arg });
return 'done';
},
};The renderer can call the callback (possibly asynchronously); the call is sent to the main process via IPC and the registered function runs there.
API
Main (electron-wcap/main)
createApiProvider<ApiInterface>(webContents, apiKey)
Returns a proxy that implementsApiInterface(andPromisify<ApiInterface>so methods are async). Each property access returns an async function that runs the corresponding method in the renderer viawebContents.executeJavaScript.
The proxy also has a readonlywebContentsproperty (theWebContentsyou passed in).removeAllCallbacks(apiProvider)Removes all registered callbacks associated with this API provider (i.e. webContents). Returnstrueif at least one callback was removed.removeCallback(apiProvider, name)Removes registered callbacks associated with this API provider (i.e. webContents) and name. Returnstrueif callback was removed.
Preload (electron-wcap/preload)
enableCallbacks()
Exposes__ElectronWCAPBridge__on the renderer’swindowviacontextBridge, so renderer code can invoke callbacks that were passed from the main process.
Important
- Entry points: Use
electron-wcap/mainin the main process andelectron-wcap/preloadin the preload script. Importing fromelectron-wcapalone throws an error that explains this. - Callback names: Callbacks you pass from main must be named (e.g.
function onData(x) { ... }), not anonymous, so they can be registered and invoked by name. - Sandbox: as Electron now deafult sandbox to
true, you should disable sandoxing to use callbacks. - Reload webContents: As the callback registry do not observes to webContents re/loading, you should manually drop and re-register callbacks after reloading or navigation.
Develop
See DEVELOP.md.
License
See LICENSE.
