Back to browse
Electron IPC Bridge- Auto-generated type-safety without the boilerplate

Electron IPC Bridge- Auto-generated type-safety without the boilerplate

by StrangeSound·Feb 22, 2026·1 point·0 comments

AI Analysis

●●SolidBig BrainSolve My Problem

NestJS-style decorators for Electron IPC, but Tauri and native bindings already solved this.

Strengths
  • Decorator-based API eliminates manual channel management and preload wiring boilerplate.
  • Vite plugin generates TypeScript types at build time, catching contract mismatches early.
  • Clean mental model (Controller → endpoint → typed window.ipc call) translates NestJS patterns idiomatically.
Weaknesses
  • Electron itself is declining; Tauri offers better type safety with Rust and zero runtime overhead.
  • No evidence of production usage, edge case handling, or comparison to existing solutions like electron-rpc or simple-rpc.
Target Audience

Electron app developers seeking to eliminate IPC boilerplate and maintain type safety.

Similar To

electron-rpc · electron-ipc-utils · Tauri (alternative approach)

Post Description

Hey HN,

In 2024 my son was born, and during the long nights of frequent wake-ups, I started (and never finished...) building an Electron app. I very quickly found that the boilerplate required to wire up the main and renderer processes to be very cumbersome, and I'm sure like many others, started to build abstractions around it to make life easier.

Having been heavily indoctrinated in the NestJS ecosystem through my workplace, I started to grow fond of DI, decorators, and the declarative style of working.

My first attempt at abstraction was fairly mediocre, but I recently decided to have a second crack. I leaned more heavily into decorators so that I could give the library a clean syntax that was simple to use. I then packaged it up so that others can use it too.

Electron IPC Bridge allows you to decorate your classes in the main process, and automatically configures the contracts in the preload. The accompanying vite plugin generates types from those contracts and ensures type-safety in the renderer. Change your contracts? The types update too. Easy!

Before:

// Main ipcMain.handle("users.get_profile", async (_event, userId: string) => { return userService.getProfile(userId); });

// Preload // Easy to make a mistake with the channel, or forget to register contextBridge.exposeInMainWorld("api", { getProfile: (id: string) => ipcRenderer.invoke("users.get_profile", id), });

// Renderer // No type-safety const profile = await window.api.getProfile(userId);

After:

// Main @IpcController() class UsersController { @IpcHandle() async getProfile(userId: string) { return userService.getProfile(userId); } }

// Preload setupPreload();

// Renderer // 100% Type-safe, auto-generated contracts with IDE autocomplete const profile = await window.api.users.getProfile(userId);

I've also tried to supply a few different DI library examples too to help people get started. I took my original unfinished app and managed to migrate it fairly painlessly! It's also using Nest now instead of typedi.

AI Disclosure: Core: About ~90% handwritten with some assistance and refactoring in places Vite plugin: Around 50/50, leaning towards AI leading where my experience with Vite is lacking Docs: Mostly written by me, but AI planned site structure, and reviewed and edited what I wrote. It also wrote the troubleshooting page and generated some diagrams for me.

This post was all me!

Similar Projects