moonrpc is a gRPC library for MoonBit. It runs the gRPC over HTTP/2 protocol itself — frames, flow control, HPACK — and splits the work into two pure engines that exchange frames in memory, with a native socket layer only where a socket is unavoidable.
moon add moonbitstack/moonrpc
Read the guide Run it in the browser
the engines never see a socket — they trade frames like any other value.
The client engine and the server engine are pure functions: hand them an Array[@http2.Frame], get back the frames to send. Nothing about them is tied to a transport. Only src/net — the real TCP layer — is native. That single split is why the same library, unchanged, runs in a browser demo and on a server.
Array[@http2.Frame]src/net is flagged supported_targets="native".One SayHello request, traced end to end. The client and server engines produced exactly these nine HTTP/2 frames. This is not a diagram of an idea — it is the output of the real engine, the same one that runs in the browser showcase below.
Verified trace from the real engine (docs/engine/moonrpc.js). Run all four call kinds live in the Showcase.
gRPC defines four call kinds. moonrpc implements all of them as the same frame machinery — only the number of messages each side sends differs.
A single request, a single response. SayHello: one message in, one message out.
The server keeps the stream open and sends a sequence. Counter.Up ticks 1, 2, 3…
The client streams a sequence, the server replies once. Sum.Add folds them.
Both sides stream. Chat.Talk is a live conversation, interleaved.
Everything here is implemented in the library, not deferred to a sidecar or proxy.
Wire-compatible gRPC over HTTP/2 — no proxy, no envoy, no translation layer.
RFC 9113 frames, streams and flow control implemented in MoonBit.
RFC 7541 header compression, dynamic table included.
The gRPC Status, mapped from HTTP/2 and HTTP errors.
Per-call request and response metadata, with the base64 key rules.
grpc.health.v1 and grpc.reflection.v1 built in — grpcurl works.
Derive handlers, registrars and descriptors straight from your types.
gRPC A6 policy, throttling and pushback around every call.
Connectivity state, balancers, DNS resolution and a channel pool.