Overview
Cap’n Web is a JavaScript-native RPC system from the creator of Cap’n Proto, redesigned for the web stack. It has no schemas and almost no boilerplate: you define a class on the server, and clients call its methods as if they were local — over HTTP, WebSocket, or postMessage().
Under the hood it is an object-capability protocol, which makes it far more expressive than typical RPC: you can pass functions and objects by reference, call in both directions, and chain dependent calls into a single network round trip.
Key Features
- No schemas, no codegen, no build step — install the package and start calling methods
- TypeScript-friendly with typed stubs for remote objects
- Human-readable wire format — it is JSON with light pre/post-processing
- Multiple transports: HTTP batch, WebSocket, and
postMessage(), extensible to others - Runs everywhere: browsers, Cloudflare Workers, Node.js, Bun, Deno
- Promise pipelining: use the result of one call as the input of the next without waiting for a round trip
- Bidirectional calls and pass-by-reference for callbacks and capability-based security
- Tiny: under 16 kB minified and gzipped, with zero dependencies
Getting Started
npm i capnweb
A client connects and calls a remote method:
import { newWebSocketRpcSession } from "capnweb";
const api = newWebSocketRpcSession("wss://example.com/api");
console.log(await api.hello("World"));
On the server — for example a Cloudflare Worker — you expose a class that extends RpcTarget:
import { RpcTarget, newWorkersRpcResponse } from "capnweb";
class MyApi extends RpcTarget {
hello(name) {
return `Hello, ${name}!`;
}
}
export default {
fetch(request) {
return newWorkersRpcResponse(request, new MyApi());
},
};
Use Cases
- Typed client/server APIs without maintaining REST endpoints or GraphQL schemas
- Real-time apps over WebSockets with server-to-client callbacks
- Communication between Workers, iframes, and web workers
License
MIT License.