
Security News
ECMAScript 2025 Finalized with Iterator Helpers, Set Methods, RegExp.escape, and More
ECMAScript 2025 introduces Iterator Helpers, Set methods, JSON modules, and more in its latest spec update approved by Ecma in June 2025.
The 'birpc' npm package is a lightweight library for creating bidirectional RPC (Remote Procedure Call) communication between different contexts, such as between a web worker and the main thread, or between an iframe and its parent window. It simplifies the process of sending and receiving messages, handling responses, and managing errors.
Basic RPC Communication
This feature allows you to set up basic RPC communication between two contexts. In this example, the main thread defines an 'add' function that can be called from the worker.
const { createBirpc } = require('birpc');
// In the main thread
const rpc = createBirpc({
add: (a, b) => a + b
}, {
post: (msg) => worker.postMessage(msg),
on: (fn) => worker.onmessage = (e) => fn(e.data)
});
// In the worker
const rpc = createBirpc({}, {
post: (msg) => postMessage(msg),
on: (fn) => onmessage = (e) => fn(e.data)
});
// Call the 'add' function from the worker
rpc.add(1, 2).then(result => console.log(result)); // 3
Error Handling
This feature demonstrates how to handle errors in RPC communication. The main thread defines a function that throws an error, and the worker catches and logs the error message.
const { createBirpc } = require('birpc');
// In the main thread
const rpc = createBirpc({
throwError: () => { throw new Error('Something went wrong'); }
}, {
post: (msg) => worker.postMessage(msg),
on: (fn) => worker.onmessage = (e) => fn(e.data)
});
// In the worker
const rpc = createBirpc({}, {
post: (msg) => postMessage(msg),
on: (fn) => onmessage = (e) => fn(e.data)
});
// Call the 'throwError' function from the worker
rpc.throwError().catch(err => console.error(err.message)); // 'Something went wrong'
Bidirectional Communication
This feature shows how to set up bidirectional communication, where both the main thread and the worker can define and call functions on each other.
const { createBirpc } = require('birpc');
// In the main thread
const rpc = createBirpc({
mainFunction: () => 'Hello from main thread'
}, {
post: (msg) => worker.postMessage(msg),
on: (fn) => worker.onmessage = (e) => fn(e.data)
});
// In the worker
const rpc = createBirpc({
workerFunction: () => 'Hello from worker'
}, {
post: (msg) => postMessage(msg),
on: (fn) => onmessage = (e) => fn(e.data)
});
// Call the 'workerFunction' from the main thread
rpc.workerFunction().then(result => console.log(result)); // 'Hello from worker'
// Call the 'mainFunction' from the worker
rpc.mainFunction().then(result => console.log(result)); // 'Hello from main thread'
Comlink is a library that makes WebWorkers enjoyable. It allows you to use WebWorkers as if they were local objects. Compared to birpc, Comlink provides a more seamless and higher-level abstraction for working with WebWorkers, but it is primarily focused on WebWorkers and may not be as flexible for other contexts.
Postmate is a powerful, simple, promise-based library for cross-domain iframe communication. It allows you to easily communicate between an iframe and its parent window. While birpc can also handle iframe communication, Postmate is specifically designed for this purpose and provides a more specialized API.
rpc-websockets is a library for creating RPC servers and clients over WebSockets. It is more suitable for networked applications where WebSocket communication is required. Compared to birpc, rpc-websockets is more focused on network communication rather than inter-context communication within the same application.
Message-based two-way remote procedure call. Useful for WebSockets and Workers communication.
When using WebSocket, you need to pass your custom serializer and deserializer.
import type { ServerFunctions } from './types'
const ws = new WebSocket('ws://url')
const clientFunctions: ClientFunctions = {
hey(name: string) {
return `Hey ${name} from client`
}
}
const rpc = createBirpc<ServerFunctions>(
clientFunctions,
{
post: data => ws.send(data),
on: data => ws.on('message', data),
// these are required when using WebSocket
serialize: v => JSON.stringify(v),
deserialize: v => JSON.parse(v),
},
)
await rpc.hi('Client') // Hi Client from server
import type { ClientFunctions } from './types'
import { WebSocketServer } from 'ws'
const serverFunctions: ServerFunctions = {
hi(name: string) {
return `Hi ${name} from server`
}
}
const wss = new WebSocketServer()
wss.on('connection', (ws) => {
const rpc = createBirpc<ClientFunctions>(
serverFunctions,
{
post: data => ws.send(data),
on: fn => ws.on('message', fn),
serialize: v => JSON.stringify(v),
deserialize: v => JSON.parse(v),
},
)
await rpc.hey('Server') // Hey Server from client
})
As JSON.stringify
does not supporting circular references, we recommend using structured-clone-es
as the serializer when you expect to have circular references.
import { parse, stringify } from 'structured-clone-es'
const rpc = createBirpc<ServerFunctions>(
functions,
{
post: data => ws.send(data),
on: fn => ws.on('message', fn),
// use structured-clone-es as serializer
serialize: v => stringify(v),
deserialize: v => parse(v),
},
)
MessageChannel will automatically serialize the message and support circular references out-of-box.
export const channel = new MessageChannel()
import type { AliceFunctions } from './types'
import { channel } from './channel'
const Bob: BobFunctions = {
hey(name: string) {
return `Hey ${name}, I am Bob`
}
}
const rpc = createBirpc<AliceFunctions>(
Bob,
{
post: data => channel.port1.postMessage(data),
on: fn => channel.port1.on('message', fn),
},
)
await rpc.hi('Bob') // Hi Bob, I am Alice
import type { BobFunctions } from './types'
import { channel } from './channel'
const Alice: AliceFunctions = {
hi(name: string) {
return `Hi ${name}, I am Alice`
}
}
const rpc = createBirpc<BobFunctions>(
Alice,
{
post: data => channel.port2.postMessage(data),
on: fn => channel.port2.on('message', fn),
},
)
await rpc.hey('Alice') // Hey Alice, I am Bob
Refer to ./test/group.test.ts as an example.
MIT License © 2021 Anthony Fu
FAQs
Message based Two-way remote procedure call
The npm package birpc receives a total of 1,873,630 weekly downloads. As such, birpc popularity was classified as popular.
We found that birpc demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
ECMAScript 2025 introduces Iterator Helpers, Set methods, JSON modules, and more in its latest spec update approved by Ecma in June 2025.
Security News
A new Node.js homepage button linking to paid support for EOL versions has sparked a heated discussion among contributors and the wider community.
Research
North Korean threat actors linked to the Contagious Interview campaign return with 35 new malicious npm packages using a stealthy multi-stage malware loader.