You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Document the new Bun WebSocket support added in the previous commit. Add an
HTTP server on Bun section showing both the zero-wiring newBunWebSocketRpcHandler
API and the lower-level newBunWebSocketRpcSession escape hatch. Add Bun to the
introductory runtime list, note in the other runtimes section that Bun's
ServerWebSocket requires the dedicated API, and update the custom transports
section to list all four built-in transports.
Copy file name to clipboardExpand all lines: README.md
+70-1Lines changed: 70 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ Cap'n Web is a spiritual sibling to [Cap'n Proto](https://capnproto.org) (and is
6
6
* That said, it integrates nicely with TypeScript.
7
7
* Also unlike Cap'n Proto, Cap'n Web's underlying serialization is human-readable. In fact, it's just JSON, with a little pre-/post-processing.
8
8
* It works over HTTP, WebSocket, and postMessage() out-of-the-box, with the ability to extend it to other transports easily.
9
-
* It works in all major browsers, Cloudflare Workers, Node.js, and other modern JavaScript runtimes.
9
+
* It works in all major browsers, Cloudflare Workers, Node.js, Bun, Deno, and other modern JavaScript runtimes.
10
10
The whole thing compresses (minify+gzip) to under 10kB with no dependencies.
11
11
12
12
Cap'n Web is more expressive than almost every other RPC system, because it implements an object-capability RPC model. That means it:
@@ -630,6 +630,71 @@ Deno.serve(async (req) => {
630
630
});
631
631
```
632
632
633
+
### HTTP server on Bun
634
+
635
+
Bun's server-side WebSocket API uses [callback-based handlers](https://bun.sh/docs/runtime/http/websockets) instead of the standard `addEventListener` interface. Cap'n Web provides `newBunWebSocketRpcHandler()` which returns a handler object you can pass directly to `Bun.serve()`:
// Pass the handler directly — no manual wiring needed.
668
+
websocket: rpcHandler,
669
+
});
670
+
```
671
+
672
+
If you need to attach custom data to connections or add your own logic to the WebSocket handlers, use `newBunWebSocketRpcSession()` instead, which gives you direct access to the transport:
Every runtime does HTTP handling and WebSockets a little differently, although most modern runtimes use the standard `Request` and `Response` types from the Fetch API, as well as the standard `WebSocket` API. You should be able to use these two functions (exported by `capnweb`) to implement both HTTP batch and WebSocket handling on all platforms:
@@ -654,6 +719,8 @@ function newWebSocketRpcSession(
654
719
: Disposable;
655
720
```
656
721
722
+
Note: Bun's `ServerWebSocket` does not implement the standard `WebSocket``addEventListener` interface. If you are using Bun, use the dedicated `newBunWebSocketRpcHandler()` or `newBunWebSocketRpcSession()` described above.
723
+
657
724
### HTTP server using Hono
658
725
659
726
If your app is built on [Hono](https://hono.dev/) (on any runtime it supports), check out [`@hono/capnweb`](https://github.com/honojs/middleware/tree/main/packages/capnweb).
@@ -735,4 +802,6 @@ let stub: RemoteMainInterface = session.getRemoteMain();
735
802
// Now we can call methods on the stub.
736
803
```
737
804
805
+
Cap'n Web's built-in transports (WebSocket, MessagePort, HTTP batch, and Bun ServerWebSocket) are all implemented on top of this interface.
806
+
738
807
Note that sessions are entirely symmetric: neither side is defined as the "client" nor the "server". Each side can optionally expose a "main interface" to the other. In typical scenarios with a logical client and server, the server exposes a main interface but the client does not.
0 commit comments