{"id":35797841,"url":"https://github.com/mavolostudio/electron-rpc","last_synced_at":"2026-01-26T06:13:48.446Z","repository":{"id":334151206,"uuid":"1128824731","full_name":"mavolostudio/electron-rpc","owner":"mavolostudio","description":"A completely type-safe RPC (Remote Procedure Call) library for Electron applications. It eliminates the need for manual IPC event handling and ensures that your main and renderer processes stay in sync with strict TypeScript validation.","archived":false,"fork":false,"pushed_at":"2026-01-23T08:57:53.000Z","size":1761,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-23T21:03:22.072Z","etag":null,"topics":["electron","ipc","rpc","trpc","type-safe","typescript","zod"],"latest_commit_sha":null,"homepage":"https://electron-rpc-docs.moh-falah-isnan.workers.dev/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mavolostudio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-06T07:49:59.000Z","updated_at":"2026-01-23T08:57:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mavolostudio/electron-rpc","commit_stats":null,"previous_names":["mavolostudio/electron-rpc"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/mavolostudio/electron-rpc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mavolostudio%2Felectron-rpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mavolostudio%2Felectron-rpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mavolostudio%2Felectron-rpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mavolostudio%2Felectron-rpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mavolostudio","download_url":"https://codeload.github.com/mavolostudio/electron-rpc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mavolostudio%2Felectron-rpc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28768136,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T03:54:34.369Z","status":"ssl_error","status_checked_at":"2026-01-26T03:54:33.031Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["electron","ipc","rpc","trpc","type-safe","typescript","zod"],"created_at":"2026-01-07T10:15:22.219Z","updated_at":"2026-01-26T06:13:48.440Z","avatar_url":"https://github.com/mavolostudio.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @mavolostudio/electron-rpc\n\n## Introduction\n\nA type-safe RPC (Remote Procedure Call) library for Electron applications. It simplifies communication between the main process and renderer process by ensuring type safety and code completion using a natural, proxy-based API.\n\n\u003e **Not gRPC, Just IPC**\n\u003e\n\u003e Unlike gRPC, RMI, or remote object proxies, this library **does not** give the renderer direct access to Node.js functions or objects. It strictly uses Electron's standard IPC to pass serializable messages (JSON).\n\u003e\n\u003e This design ensures that **no backend code is executed directly by the renderer**. The renderer simply requests a predefined procedure by name (string), and the main process decides how to handle it.\n\n\n## Features\n\n- 🔒 **Type-Safe**: End-to-end type safety from main to renderer.\n- 🚀 **Proxy-Based**: Call server methods as if they were local functions.\n- 🧩 **Flexible**: Supports nested API structures (e.g. `api.users.get(...)`).\n- 🛡️ **Secure**: Built-in channel whitelisting and context isolation support.\n\n## Installation\n\n```bash\npnpm add @mavolostudio/electron-rpc\n```\n\n## Usage\n\n### 1. Define Context (Shared/Main)\n\nDefine the context that will be available to all procedures.\n\n```typescript\n// src/main/context.ts\nimport { IpcMainInvokeEvent } from 'electron';\n\nexport type AppContext = {\n  user: { id: string; role: 'admin' | 'user' };\n};\n\nexport async function createContext(event: IpcMainInvokeEvent): Promise\u003cAppContext\u003e {\n  return {\n    user: { id: 'user-1', role: 'admin' }, // Load from session/token\n  };\n}\n```\n\n### 2. Define Procedures (Shared/Main)\n\nUse the `ProcedureBuilder` to define your API with validation and middleware.\n\n```typescript\n// src/main/router.ts\nimport { createProcedure, z } from '@mavolostudio/electron-rpc';\nimport type { AppContext } from './context';\n\nconst t = createProcedure\u003cAppContext\u003e();\n\n// Middleware example\nconst logger = t.use(async ({ input }, next) =\u003e {\n  console.log('Request:', input);\n  return next();\n});\n\nexport const router = {\n  greeting: t\n    .input(z.object({ name: z.string() }))\n    .output(z.string())\n    .use(async ({ ctx }, next) =\u003e {\n      // Access context before handler\n      console.log('User:', ctx.user.id);\n      return next();\n    })\n    .query(async (ctx, input) =\u003e {\n      return `Hello, ${input.name}!`;\n    }),\n    \n  deleteData: t\n    .input(z.object({ id: z.string() }))\n    .output(z.boolean())\n    .use(async ({ ctx }, next) =\u003e {\n      if (ctx.user.role !== 'admin') throw new Error('Unauthorized');\n      return next();\n    })\n    .mutation(async (ctx, input) =\u003e {\n      // Perform dangerous action\n      return true;\n    })\n};\n\nexport type AppRouter = typeof router;\n```\n\n### 3. Register Router (Main Process)\n\nRegister the router with the IPC channel.\n\n```typescript\n// src/main/ipc.ts\nimport { registerIpcRouter } from '@mavolostudio/electron-rpc';\nimport { router } from './router';\nimport { createContext } from './context';\n\n// Listen on \"rpc\" channel\nregisterIpcRouter('rpc', router, createContext);\n```\n\n### 4. Create Client (Renderer Process)\n\n#### Option A: TanStack Query (Recommended)\n\nWrap the proxy with our TanStack Query adapter for auto-generated hooks.\n\n```typescript\n// src/renderer/client.ts\nimport { createProxy } from '@mavolostudio/electron-rpc/client';\nimport { tanstackProcedures } from '@mavolostudio/electron-rpc/tanstack-procedures';\nimport { QueryClient } from '@tanstack/react-query';\nimport type { AppRouter } from '../../main/router';\n\nconst queryClient = new QueryClient();\n\n// Create base proxy\nconst rpc = createProxy\u003cAppRouter\u003e((path, args) =\u003e \n  window.rpc.invoke('rpc', { key: path[0], input: args[0] })\n);\n\n// Create TanStack wrapper\nexport const client = tanstackProcedures(rpc, queryClient);\n```\n\n**Usage in React:**\n\n```tsx\nfunction App() {\n  const { data, isLoading } = client.greeting.useQuery({ name: 'Alice' });\n  const mutation = client.deleteData.useMutation();\n\n  if (isLoading) return \u003cdiv\u003eLoading...\u003c/div\u003e;\n\n  return (\n    \u003cbutton onClick={() =\u003e mutation.mutate({ id: '123' })}\u003e\n      {data}\n    \u003c/button\u003e\n  );\n}\n```\n\n#### Option B: Direct RPC\n\nYou can also use the RPC client directly.\n\n```typescript\n// src/renderer/client.ts\nimport { createProxy } from '@mavolostudio/electron-rpc/client';\nimport type { AppRouter } from '../../main/router';\n\nexport const rpc = createProxy\u003cAppRouter\u003e((path, args) =\u003e \n  window.rpc.invoke('rpc', { key: path[0], input: args[0] })\n);\n\n// Usage\nconst result = await rpc.greeting({ name: 'Bob' });\n```\n\n## API Reference\n\n### `createProcedure\u003cContext\u003e()`\nCreates a builder for defining procedures with input/output validation and middleware.\n\n### `registerIpcRouter(channel, router, createContext, plugins?)`\nRegisters a router object to handle IPC requests.\n- `channel`: IPC channel name.\n- `router`: Object containing procedures.\n- `createContext`: Function generating context for each request.\n- `plugins`: Optional array of lifecycle plugins.\n\n### `tanstackProcedures(client, queryClient)`\nWraps the RPC client to provide `useQuery`, `useMutation`, and `getQueryKey`.\n\n### `exposeRpc(config)`\nExposes the secure bridge in the preload script.\n- `config.name`: Global variable name (e.g., \"rpc\").\n- `config.whitelist`: Allowed channels.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmavolostudio%2Felectron-rpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmavolostudio%2Felectron-rpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmavolostudio%2Felectron-rpc/lists"}