https://github.com/nlfmt/electron-bridge
Easily define and use IPC functions and events in your Electron app. Fully typesafe.
https://github.com/nlfmt/electron-bridge
electron router rpc typescript
Last synced: about 1 year ago
JSON representation
Easily define and use IPC functions and events in your Electron app. Fully typesafe.
- Host: GitHub
- URL: https://github.com/nlfmt/electron-bridge
- Owner: nlfmt
- License: mit
- Created: 2024-01-25T10:05:28.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-02-09T19:16:14.000Z (about 2 years ago)
- Last Synced: 2025-03-07T17:05:09.016Z (about 1 year ago)
- Topics: electron, router, rpc, typescript
- Language: TypeScript
- Homepage:
- Size: 79.1 KB
- Stars: 1
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Electron Bridge
Easily define and use IPC functions and events in your Electron app. Fully typesafe. \
Inspired by [tRPC's architecture](https://trpc.io/).
## Installation
```bash
npm install @nlfmt/electron-bridge
```
```bash
pnpm add @nlfmt/electron-bridge
```
```bash
yarn add @nlfmt/electron-bridge
```
## Usage
This library is designed to be used with electron apps that enable `contextIsolation`, `sandbox` and disable `nodeIntegration`.
### Create bridge
```ts
// bridge.ts
import { createBridge, createBridgeRouter } from '@nlfmt/electron-bridge'
// You can place routers in separate files and import them here
const exampleRouter = createBridgeRouter({
log: (e, message: string) => {
console.log("Message from IPC:", message)
},
})
export const bridge = createBridge({
example: exampleRouter,
})
```
### Register bridge
```ts
// main.ts
import { bridge } from './bridge'
// This will call ipcMain.handle() under-the-hood and set up all listeners
// Don't forget to call this before you send any IPC messages
bridge.register()
```
### Register preload script
If you have `sandbox` enabled, you wont be able to import `registerBridgePreload`,
unless you are using a bundler, such as `vite` with the `vite-plugin-electron` plugin.
For a workaround, see the [Issues](#issues) section.
```ts
// preload.ts
import { registerBridgePreload } from '@nlfmt/electron-bridge/preload'
registerBridgePreload()
```
### Use bridge
```tsx
// App.tsx
import { createRendererBridge } from '@nlfmt/electron-bridge/renderer'
// Usually would be defined in a separate file like `bridge.ts`
export const bridge = createRendererBridge()
function App() {
return (
bridge.example.log("Hello from App.tsx")}>
Send message
)
}
export default App
```
### Set up Events
Register Events using the `withEvents` method on the bridge.
```ts
// bridge.ts
type RendererEvents = {
userClickedButton: { message: string }
}
type MainEvents = {
ping: { data: number }
}
export const bridge = createBridge({
example: exampleRouter,
}).withEvents()
// send events every second
setInterval(() => {
bridge.emit("ping", { data: Math.random() })
}, 1000)
bridge.on()
```
Then, use the events api in the renderer:
```tsx
// App.tsx
import { createRendererBridge } from '@nlfmt/electron-bridge/renderer'
import { useEffect } from 'react'
export const bridge = createRendererBridge()
function App() {
useEffect(() => {
// methods like `on` and `once` return a function that can be used to unsubscribe
return bridge.events.on("ping", (e, data) => {
console.log("Ping from main:", data)
})
}, [])
return (
bridge.example.log("Hello from App.tsx")}>
Send message
)
}
```
## Issues
### Preload scripts without a bundler
If you are not using a bundler, you can use the following workaround to register everything needed by the bridge:
```ts
import { contextBridge, ipcRenderer } from "electron"
contextBridge.exposeInMainWorld("__bridge", {
invoke: ipcRenderer.invoke,
emit: ipcRenderer.send,
on: (...args: Parameters) => {
ipcRenderer.on(...args)
return () => ipcRenderer.off(...args)
},
once: (...args: Parameters) => {
ipcRenderer.once(...args)
return () => ipcRenderer.off(...args)
},
off: ipcRenderer.off,
})
```
## License
See [LICENSE](LICENSE) for more information.