Why gRPC Never Caught On in Frontend Development
Backend developers are accustomed to using gRPC, Protobuf, and Avro for network communication. But when moving to the frontend, REST becomes cumbersome: there's no convenient contract, and Swagger requires synchronization from both sides. JSON introduces complexities—the backend marshals data, and the frontend fears breaking changes. Requests turn into chains like resp?.body?[i]?.creds?.card?.number.
gRPC solves these issues with typing and code generation. So why isn't it used on the frontend?
Problems with Code Generation from OpenAPI and Swagger
Auto-generation from Swagger doesn't guarantee stability. A backend developer changes fields and forgets to update the specification—the frontend breaks. Organizational issues are inevitable: vacations, urgent tasks.
GraphQL from Facebook promised a solution: strict schemas, introspection, code generation. Frontend developers benefited, but the backend got the downsides:
- Clients can request arbitrary depths: from
{ user { id name } }to recursiveposts { comments { author { ... } } }. - No direct mapping to database models—resolvers and union types are needed.
- N+1 query problems.
DataLoader, persisted queries, and depth limiting add complexity on the backend. In Go, GraphQL packages are particularly inconvenient.
gRPC-Web: A Compromise Without the Advantages
gRPC-Web looks like a solution: Protobuf, code generation. But it's not real gRPC.
Browsers support HTTP/2+, but without full control:
- No connection, frame, or stream management—everything goes through
fetch('/api'). - Browser → proxy via HTTP/1.1, proxy → backend via HTTP/2. The gain is only on the backend.
- Requires proxy infrastructure.
gRPC-Web becomes a data format, not a transport. The advantages are lost.
The Root Problem: Browser Limitations
Browsers block low-level access for security reasons. JS code from websites has network access, but full HTTP/2+ frames would allow:
- Scanning local networks.
- Attacks on localhost.
- Firewall bypass.
- DDoS through user connections.
HTTP/1.1 is safe thanks to sandboxing: no sockets, limited fetch and WebSocket. The browser manages multiplexing and header compression in HTTP/2+ for its own optimization, not for JS.
Promising Alternatives
Solutions exist, but none are universal:
- tRPC: For TypeScript monorepos. Types are imported directly, without code generation, over HTTP.
- Connect protocol (Buf): A layer over gRPC for fetch in browsers, with code generation.
- WebTransport: An experimental API for HTTP/3 streams in a sandbox. A direction for future development.
Key Takeaways
- REST dominates due to universality, despite contract inconveniences.
- Browser sandboxes block low-level HTTP/2+ to protect against attacks.
- gRPC-Web loses key features: streaming, multiplexing.
- tRPC, Connect, and WebTransport are niche solutions for specific tech stacks.
- The industry is moving toward sandboxed stream access via WebTransport.
REST will remain the standard until a universal contract emerges. Curl will continue to be used for debugging.
— Editorial Team
No comments yet.