gRPC in the browser without grpc-web: the wire protocol over a WebRTC DataChannel
grpc-web exists because browsers can't speak HTTP/2 trailers. The usual answer is a translation proxy in front of your service. We took a different one: run the actual gRPC wire protocol β length-prefixed frames, HPACK-f
grpc-web exists because browsers can't speak HTTP/2 trailers.
The usual answer is a translation proxy in front of your service.
We took a different one: run the actual gRPC wire protocol β
length-prefixed frames, HPACK-free, all four call shapes β over a
single WebRTC RTCDataChannel, and generate the runtime for it
from your .proto.
grpc-over-datachannels is that experiment, grown up:
- Dependency-free generated runtimes for 16 languages β JavaScript/TypeScript, Go, Rust, Python, Ruby, PHP, Lua, C, C++, Dart, Java, Kotlin, Scala, Swift, C#, and Zig. Browser and native. The generated code is stdlib-only; there is no grpc library underneath it.
- Our own WebRTC stack. ICE, DTLS, and SCTP written from scratch, so the native clients don't depend on a WebRTC library either.
- Graded against stock gRPC. The generated implementations are tested against the reference implementations through a TCPβDataChannel proxy β the oracle is the real thing, not a reimplementation of it.
- WebRTC-Direct. A server prints one certhash multiaddr; a client dials it. No signaling server. Direct on a LAN, through a TURN relay behind symmetric NAT, or full ICE with STUN in peer mode β with runnable examples in every language.
-
A Kafka proxy in Rust.
grpcdc.kafka.v1.Kafkaexposes Apache Kafka as a generated gRPC service, so any generated client β including a browser tab β can produce and consume without a Kafka client library. The same generated e2e suite runs against Kafka and Redpanda in CI.
If you only have thirty seconds, the whole pitch is a 2-minute
video: https://youtu.be/LwrXpnlMlgA β and the Kafka proxy gets
its own: https://youtu.be/KJ98a4ApZ4E
The part we're proudest of is also the strangest: almost
everything in the repos is generated. The runtimes, the tests,
the examples, and the docs come from recursive generators, so
sixteen languages can't quietly drift apart. When a language
misbehaves, we fix the generator, not sixteen codebases.
Try it without installing anything β the stub generator runs in
your browser: https://browser-grpc.github.io/grpc-over-datachannels/app/
Code, releases (npm / PyPI / NuGet / GHCR / GitHub-hosted Maven):
https://github.com/browser-grpc/grpc-over-datachannels
Longer write-ups, with the design trade-offs:
- https://c100k.blogspot.com/2026/10/introducing-grpc-over-datachannels-grpc.html
- https://c100k.blogspot.com/2026/10/kafka-over-grpc-rust-kafka-proxy-with.html
Questions and hostile edge cases welcome β the NAT and framing ones especially.
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.