Quick Start
This guide walks through a minimal setup where a renderer process calls procedures on the main process.
-
Define your tRPC router (main process)
src/main/router.ts import { initTRPC } from '@trpc/server';import { z } from 'zod';const t = initTRPC.create();export const appRouter = t.router({greet: t.procedure.input(z.object({ name: z.string() })).query(({ input }) => {return `Hello, ${input.name}!`;}),});export type AppRouter = typeof appRouter; -
Attach your router to the window (main process)
src/main/index.ts import { app, BrowserWindow } from 'electron';import { createWindowMessagePortHandler } from 'electron-messageport-trpc/main';import { appRouter } from './router';app.whenReady().then(() => {const win = new BrowserWindow({webPreferences: {preload: '/path/to/preload.js',},});win.loadFile('index.html');createWindowMessagePortHandler({router: appRouter,windows: [win],});}); -
Expose the port receiver (preload script)
src/preload/index.ts import { exposePortReceiver } from 'electron-messageport-trpc/preload';exposePortReceiver(); -
Create the tRPC client (renderer process)
src/renderer/index.ts import { createTRPCClient } from '@trpc/client';import { getPort, portLink } from 'electron-messageport-trpc/renderer';import type { AppRouter } from '../main/router';const trpc = createTRPCClient<AppRouter>({links: [portLink({ port: getPort() })],});// Now you can call procedures with full type safety!const greeting = await trpc.greet.query({ name: 'World' });console.log(greeting); // "Hello, World!"
What Just Happened?
Section titled “What Just Happened?”createWindowMessagePortHandler()watches each window fordid-finish-load, creates a new MessagePort pair, and attaches the main-process side to your router.exposePortReceiver()in the preload script receives the transferred port and forwards it into the renderer’s main world.- In the renderer,
getPort()resolves the transferred port andportLink({ port })plugs it into a standard tRPC client. - Reloads are handled by the main-process helper, so your application code does not need to manually recreate handlers.
Next Steps
Section titled “Next Steps”- Subscriptions — real-time data streaming with tRPC subscriptions
- API Reference — detailed documentation for every export