# capnweb
**Repository Path**: mirrors_cloudflare/capnweb
## Basic Information
- **Project Name**: capnweb
- **Description**: JavaScript/TypeScript-native, low-boilerplate, object-capability RPC system
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-09-23
- **Last Updated**: 2026-09-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README

Cap'n Web: A JavaScript-native RPC system
Cap'n Web is a spiritual sibling to [Cap'n Proto](https://capnproto.org) (and is created by the
same author), but designed to play nice in the web stack. That means:
* Like Cap'n Proto, it is an **object-capability protocol**. ("Cap'n" is short for "capabilities
and.") It's incredibly powerful.
* Unlike Cap'n Proto, Cap'n Web has **no schemas**. In fact, it has almost no boilerplate
whatsoever. This means it works more like the
[JavaScript-native RPC system in Cloudflare Workers](https://blog.cloudflare.com/javascript-native-rpc/).
* That said, it integrates nicely with TypeScript.
* Also unlike Cap'n Proto, Cap'n Web's underlying serialization is **human-readable**. It's just
JSON, with a little pre- and post-processing.
* It works over HTTP, WebSocket, and `postMessage()` out of the box, and can be extended to other
transports easily.
* It works in all major browsers, Cloudflare Workers, Node.js, Bun, Deno, and other modern
JavaScript runtimes.
The whole thing compresses (minify + gzip) to **under 16 kB with no dependencies**.
Cap'n Web is more expressive than almost every other RPC system, because it implements an
object-capability RPC model. That means it supports **bidirectional calling**, **passing functions
and objects by reference**, **promise pipelining** (chaining dependent calls into a single network
round trip), and **capability-based security patterns**, where holding a reference *is* the
permission to use it.
## Installation
[Cap'n Web is an npm package.](https://www.npmjs.com/package/capnweb)
```sh
npm i capnweb
```
There is no build step, no schema compiler, and no code generation.
```js
import { RpcTarget, newWebSocketRpcSession } from "capnweb";
```
To use `using` declarations, your `tsconfig.json` needs `"target": "esnext"` and matching `lib`s.
See [Installation](packages/docs/src/content/docs/start/installation.mdx).
## Example
A client looks like this:
```js
import { newWebSocketRpcSession } from "capnweb";
// One-line setup.
let api = newWebSocketRpcSession("wss://example.com/api");
// Call a method on the server!
let result = await api.hello("World");
console.log(result);
```
Here's the server:
```js
import { RpcTarget, newWorkersRpcResponse } from "capnweb";
// This is the server implementation.
class MyApiServer extends RpcTarget {
hello(name) {
return `Hello, ${name}!`
}
}
// Standard Cloudflare Workers HTTP handler.
//
// (Node, Deno, Bun and other runtimes are supported too.)
export default {
fetch(request, env, ctx) {
// Parse URL for routing.
let url = new URL(request.url);
// Serve API at `/api`.
if (url.pathname === "/api") {
return newWorkersRpcResponse(request, new MyApiServer());
}
// You could serve other endpoints here...
return new Response("Not found", {status: 404});
}
}
```
And here is the part that makes it interesting. Three dependent calls, one round trip:
```ts
using api = newHttpBatchRpcSession("https://example.com/api");
// No awaits, so no round trips yet.
using authed = api.authenticate(apiToken);
let friendIds = authed.getFriendIds();
// One await. One round trip. Everything above travelled together.
let friends = await friendIds.map(id => api.getUserProfile(id));
```
## Documentation
**The [documentation site](packages/docs/) is the source of truth.** It is an Astro + Starlight site
under [`packages/docs/`](packages/docs/), and every page is readable as Markdown directly on GitHub.
Start here:
| Page | What it covers |
| --------------------------------------------------------------------------- | ---------------------------------------------------- |
| [Introduction](packages/docs/src/content/docs/start/introduction.mdx) | What Cap'n Web is and why object capabilities matter |
| [Quickstart](packages/docs/src/content/docs/start/quickstart.mdx) | A working client and server |
| [Pipelining tour](packages/docs/src/content/docs/start/pipelining-tour.mdx) | The part that makes it fast |
| [How it compares](packages/docs/src/content/docs/guides/comparisons.mdx) | Against tRPC, JSON-RPC, GraphQL and Cap'n Proto |
Core concepts:
[What can be passed](packages/docs/src/content/docs/concepts/values.mdx) ·
[RpcTarget](packages/docs/src/content/docs/concepts/rpc-target.mdx) ·
[RpcStub](packages/docs/src/content/docs/concepts/stubs.mdx) ·
[RpcPromise & pipelining](packages/docs/src/content/docs/concepts/promises.mdx) ·
[The magic `map()`](packages/docs/src/content/docs/concepts/map.mdx) ·
[Streaming](packages/docs/src/content/docs/concepts/streaming.mdx) ·
[Disposal](packages/docs/src/content/docs/concepts/disposal.mdx)
Transports:
[Overview](packages/docs/src/content/docs/transports/index.mdx) ·
[HTTP batch](packages/docs/src/content/docs/transports/http-batch.mdx) ·
[WebSocket](packages/docs/src/content/docs/transports/websocket.mdx) ·
[MessagePort](packages/docs/src/content/docs/transports/message-port.mdx) ·
[Custom](packages/docs/src/content/docs/transports/custom.mdx)
Server runtimes:
[Cloudflare Workers](packages/docs/src/content/docs/servers/workers.mdx) ·
[Node.js](packages/docs/src/content/docs/servers/node.mdx) ·
[Deno](packages/docs/src/content/docs/servers/deno.mdx) ·
[Bun](packages/docs/src/content/docs/servers/bun.mdx) ·
[Hono](packages/docs/src/content/docs/servers/hono.mdx) ·
[Other](packages/docs/src/content/docs/servers/other.mdx)
Guides and reference:
[Security considerations](packages/docs/src/content/docs/guides/security.mdx) ·
[Sessions & reconnection](packages/docs/src/content/docs/guides/sessions.mdx) ·
[Runtime validation](packages/docs/src/content/docs/guides/validation.mdx) ·
[Workers RPC interop](packages/docs/src/content/docs/guides/workers-rpc.mdx) ·
[Wire protocol](packages/docs/src/content/docs/reference/protocol.mdx) ·
[API cheat sheet](packages/docs/src/content/docs/reference/api.mdx)
To run the site locally, with both examples embedded as live in-browser playgrounds:
```sh
pnpm install && pnpm run dev:docs
```
## Examples
Runnable examples live in [`examples/`](examples/):
* [`batch-pipelining`](examples/batch-pipelining/): three dependent calls in one HTTP round trip.
* [`worker-react`](examples/worker-react/): a React app against a Cap'n Web Worker, with runtime
validation at the RPC boundary.
* [`session-recovery`](examples/session-recovery/): a WebSocket session with a button that kills
it, showing what a disconnect destroys and what it takes to resume without a gap.
## Related packages
* [`capnweb-validate`](packages/capnweb-validate/): generates runtime validators from your
TypeScript types at build time, since TypeScript types are erased and a malicious peer can send
anything.
## Security
Cap'n Web gives you strong authorization tools, but a few things are your responsibility:
authenticating in-band rather than with cookies, rate-limiting because pipelining is cheap for
attackers, setting transport payload limits, and validating types at runtime. Read
[Security considerations](packages/docs/src/content/docs/guides/security.mdx) before exposing a
service to untrusted peers.
To report a vulnerability, see [SECURITY.md](SECURITY.md).
## Contributing
Bug reports and pull requests are welcome. Note that `packages/docs/` is the source of truth for
user-facing documentation; behaviour changes should update the relevant page there.
## License
[MIT](LICENSE.txt)