When you define a service class in the main process, every public method becomes callable from the renderer process. Zenbu.js handles all the wiring between processes for you, so you just call methods like normal functions. Under the hood, communication happens over a WebSocket, which means the same RPC system works whether your app runs in Electron or in the browser. The transport is pluggable, so you can swap it for Electron IPC, WebRTC, or anything else. Services are scoped under their owning plugin’s name. For a plugin namedDocumentation Index
Fetch the complete documentation index at: https://zenbulabs.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
app, the call site is rpc.app.<service>.<method>(...). Core’s own services live under rpc.core.<service>.
Type inference
TypeScript types flow from the service definition to the renderer call site. Parameters, return types, and method names are all inferred. Types are generated byzen link (runs automatically during zen dev) and stored in .zenbu/types/, so if you rename a method or change its signature, the renderer code shows a type error immediately.
Async
All RPC calls are async from the renderer’s perspective, even if the service method is synchronous. This is because calls cross a process boundary.Error handling
Errors thrown in service methods are serialized and re-thrown in the renderer.Method conventions
- Take a single object argument. This keeps argument signatures stable as the API grows.
- Return JSON-serializable values. Anything that round-trips through
JSON.stringifyworks.

