Registering Express Routes
A common pattern is to fetch data from your VA’s external API in the background module and expose it locally:Communication Between Background and UI
For UI-to-background communication, the recommended pattern is Express routes + TanStack Query. Register routes in your background module withctx.server.registerRouter() and query them from your UI module using TanStack Query, as shown in the Registering Express Routes section above.
This approach composes naturally with React’s rendering model — loading states, error handling, caching, and refetching all come for free via TanStack Query.
For background-to-UI push (data the UI didn’t ask for, like live updates or alerts), you can use ctx.ipc.send(). UI modules subscribe with socket.on from usePluginContext() — both ends use the leaf event name, the shell scopes the channel to your plugin id automatically.
- Leaf names only. Don’t include
plugin:{id}:in the channel — the shell prefixes both ends, doubling it would broadcast to nothing. - Fire-and-forget. A UI that mounts after a broadcast doesn’t see it. Pattern: HTTP fetch on mount, then subscribe for updates.
- Same plugin only. Plugin A’s UI cannot subscribe to plugin B’s broadcasts.
- No UI → background
socket.emit. Use HTTP viactx.server.registerRouterinstead. - Structured-cloneable payloads. Functions, DOM nodes, and class instances with methods do not survive Electron IPC serialization.