AOCyber
Abstract illustration of a hexagonal framework core connecting to multiple product modules

From Fork to Framework, Part 6: ConnectRPC, Eden Libs, and the Framework That Pays for Itself

March 31, 2026

ConnectRPC is the RPC (remote procedure call, a way for one program to ask another program to run a function over the network) framework we chose to bind every Go backend and Flutter client in our ecosystem together, and after shipping five production platforms on it, we are convinced it is the most practical alternative to hand-rolled REST APIs available today. In particular, ConnectRPC solves a problem that has quietly cost engineering teams years of productivity: the gap between what a server promises and what a client actually receives. This guide covers everything you need to know about ConnectRPC — what it is, how it compares to gRPC and gRPC-Web, how to implement it step by step, and how one team used it to ship a full product in eight days. If you have ever maintained a hand-written OpenAPI spec that drifted out of sync with your real API, this article will show you a better way.

ConnectRPC architecture diagram showing a Go server and Flutter client connected through a shared Protocol Buffers contract

What Is ConnectRPC?

ConnectRPC is an open-source RPC framework built by the team at Buf as a simpler, browser-friendly evolution of gRPC. Rather than inventing a new wire format, ConnectRPC defines a protocol that speaks three dialects fluently: its own Connect protocol, standard gRPC, and gRPC-Web. As a result, a single server implementation can serve mobile apps, backend services, and web browsers without any protocol translation layer in between.

At its core, ConnectRPC relies on Protocol Buffers (often shortened to "protobuf"), a language-neutral format for describing structured data. A service is defined once in a .proto file, and the ConnectRPC toolchain generates fully typed server stubs and client code from that single definition. Consequently, if a field type changes, both the server and every client fail to compile immediately. There is no hand-written REST model, no OpenAPI specification that drifts from reality, and no runtime type mismatch that reaches production.

In short: ConnectRPC turns your API contract into a single source of truth that both your backend and your clients are physically unable to disagree with.

ConnectRPC vs. gRPC vs. gRPC-Web: Choosing the Right Protocol

Raw gRPC is fast and strongly typed, but it was designed for server-to-server traffic over HTTP/2. Browsers cannot speak raw gRPC, which is why the ecosystem invented gRPC-Web — a workaround that still typically requires an Envoy proxy to translate between the browser-safe format and true gRPC. ConnectRPC removes that requirement entirely.

  • ConnectRPC works natively over HTTP/1.1 and HTTP/2, so it runs directly in browsers, mobile apps, and curl commands with zero translation layer.
  • gRPC requires HTTP/2 and specialized client libraries, which makes it awkward for web clients and difficult to debug with everyday tools.
  • gRPC-Web solves the browser problem but usually adds an Envoy sidecar, extra infrastructure, and another moving part that can fail.

The Connect Protocol vs. Traditional gRPC-Web Proxies

Because ConnectRPC is wire-compatible with both gRPC and gRPC-Web, existing gRPC infrastructure keeps working without modification. However, the Connect protocol itself also supports plain JSON serialization alongside binary protobuf. That means you can debug an API call with a standard HTTP client — no special gRPC tooling required. In contrast, debugging raw gRPC traffic usually means reaching for a dedicated inspection tool. This single difference removes an enormous amount of operational friction, especially for teams who need to demo or test an endpoint quickly.

How ConnectRPC Works: Protocol Buffers as the Contract Layer

The real power of pairing Go and Flutter is not either technology in isolation — it is the contract layer that ConnectRPC provides between them. We treat Protocol Buffers as the single source of truth for every API in our system. Specifically, the workflow looks like this: an engineer defines a service in a .proto file, runs buf generate, and immediately receives a Go server interface to implement plus a Dart client class to call. The types match. The fields match. The error codes match. The entire API surface is verified at compile time on both sides of the wire — long before any code reaches a staging environment.

If you have followed our earlier work on this stack, you already know we started this journey somewhere very different. We documented the full path in Part 1 of this series, where we forked LibreChat and began standing on the shoulders of giants, long before ConnectRPC entered the picture.

Key Features That Make ConnectRPC Stand Out

Beyond browser compatibility, ConnectRPC brings a handful of features that compound over time as a platform grows:

  • Idiomatic generated code. Generated Go and Dart code reads like code a senior engineer would write by hand, not auto-generated boilerplate.
  • Streaming support. ConnectRPC supports server streaming, client streaming, and bidirectional streaming for real-time features like live updates.
  • Interceptors. A middleware system that operates on typed messages instead of raw bytes, covered in detail below.
  • No sidecar required. There is no Envoy proxy, no protocol translation layer, and no special-cased browser client to maintain.
  • Multi-language support. Official implementations exist for Go, Swift, Kotlin, and TypeScript/Node, with community support extending further.

ConnectRPC Interceptors: Middleware for Every RPC Call

ConnectRPC supports interceptors, which function like HTTP middleware but operate at the RPC level with full access to typed request and response messages. Therefore, instead of parsing raw JSON bodies, an interceptor can inspect a strongly typed object before your handler ever runs. Our platform wires in three standard interceptors on every service:

  • AuthInterceptor validates tokens, resolves user identity, and injects the authenticated user into the request context, so every RPC handler receives a verified user without performing its own authentication logic. If you need to see how a credential actually gets registered before this step, our documentation on connecting a provider credential in AOCore walks through the setup.
  • RBACInterceptor checks whether the authenticated user has permission to perform the requested operation, respecting company hierarchy and role caps. As a result, authorization is enforced at the transport layer rather than scattered across individual handlers.
  • ObservabilityInterceptor records request duration, error rates, and response sizes, emitting structured logs and metrics for every RPC call without any instrumentation code inside the handlers themselves.

Product teams wire these interceptors into their ConnectRPC server once and get authentication, authorization, and observability for free on every future service. Consequently, domain handlers contain only domain logic — nothing else.

Real-World Architecture: How Eden Libs Uses ConnectRPC at Scale

To show ConnectRPC in action, consider Eden Libs — a monorepo we built in 19 commits across three days that now powers every product in our ecosystem. The architecture flows in one direction: .proto files are the single source of truth, buf generate produces a 14-package Go platform library and a fully generated Dart client library, and five consumer products build on top of both.

Layer Package Responsibility
Contract.proto filesSingle source of truth for every ConnectRPC service
Backendeden-platform-go14 packages: auth, RBAC, company hierarchy, audit, webhooks, registry, bridge
Frontend dataeden-platform-api-dartGenerated protobuf models and ConnectRPC client stubs
Frontend shelleden-platform-flutterAuth orchestration, company switcher, server-driven navigation
Designeden-ui-flutter50+ widgets, six brand presets, zero business logic
Toolingeden-cliScaffolding, codegen, and a unified dev server

eden-platform-go: 14 Packages Behind Every ConnectRPC Service

The Go platform library provides 14 packages covering the infrastructure every multi-tenant SaaS application needs. Auth handles OAuth, multi-factor authentication, and session management. Company hierarchy models parent-child organizations with ancestor and descendant queries, answering questions like "which companies sit under this reseller." RBAC enforces role caps so a company administrator can never grant permissions that exceed their own entitlements. Audit provides a tamper-evident trail for compliance. Webhooks deliver events with adaptive retry behaviour. Bridge propagates cross-domain events, and Registry lets modules register navigation and search scopes dynamically.

eden-platform-flutter: The Client Side of the Contract

On the Flutter side, the platform package provides authentication orchestration — login, logout, token refresh, and MFA challenges — along with a company switcher for users who belong to multiple organizations. In addition, server-driven navigation reads the backend registry and constructs the sidebar dynamically. Product teams never hand-build navigation; they simply register their module, and the shell handles the rest.

eden-platform-api-dart: Fully Generated ConnectRPC Clients

This package is entirely auto-generated from the .proto definitions. It contains Dart classes for every protobuf message and ConnectRPC client stubs for every service. As a result, product teams import it and call typed methods directly — there is no manual HTTP code, no JSON parsing, and no model classes to maintain by hand.

eden-ui-flutter and eden-cli: Presentation and Tooling

eden-ui-flutter supplies over 50 widgets and six brand presets, with no business logic or network calls baked in — pure presentation. Meanwhile, eden-cli provides three commands: eden new scaffolds a product with platform dependencies pre-wired, eden generate runs protobuf and model codegen, and eden dev runs a combined Go and Flutter hot-reload server.


Dual-Store Testing for RPC Services Without a Database

A critical design decision behind every ConnectRPC service we ship is the dual-store pattern. Every platform service depends on a Store interface rather than a concrete implementation, and we provide two implementations of it.

devstore uses in-memory maps protected by mutexes. It starts instantly, requires no infrastructure, and resets between test runs, so developers iterate at the speed of unit tests. There is no database to provision and no Docker container to start. pgstore, in contrast, uses PostgreSQL with sqlc-generated queries. It is the production implementation and the pre-merge validation target, running the same service logic, the same business rules, and the same authorization checks against a real database.

Because services depend on interfaces rather than concrete types, swapping implementations is a one-line configuration change. This also makes the entire platform testable without database fixtures: unit tests use devstore, integration tests use pgstore, and the service code never knows the difference.

How to Implement ConnectRPC in Your Stack

Getting started with ConnectRPC follows a predictable, repeatable sequence. Here is the exact process we use every time we add a new service:

  1. Define your service in a .proto file. Write the messages and RPC methods your service exposes using Protocol Buffers syntax, since this file becomes the single source of truth for both server and client.
  2. Generate server and client code with Buf. Run buf generate to produce a typed Go server interface and a typed Dart client in a single command, eliminating manual boilerplate entirely.
  3. Implement the Go server interface. Fill in the generated interface with your actual business logic, keeping handlers focused purely on domain behaviour rather than plumbing concerns.
  4. Wire up interceptors for auth, RBAC, and observability. Attach the AuthInterceptor, RBACInterceptor, and ObservabilityInterceptor to your ConnectRPC server so every request is authenticated, authorized, and logged automatically.
  5. Call the API from your Flutter client. Import the generated Dart client, instantiate it against your ConnectRPC endpoint, and call the typed method directly without writing any manual HTTP or JSON parsing code.

ConnectRPC in Production: An Eight-Day Case Study

Architecture claims are cheap. Shipping products proves them. Eden Circle, a standalone team communications product with messaging, group conferencing, screen sharing, presence tracking, push notifications, and AI features powered by AOSentry, is our strongest proof point. If you want to see how we route and optimize the AI layer behind those features, we covered it in depth in our breakdown of intelligent model routing, fallbacks, and cost optimization.

In eight days and 50 commits, a single engineer built and deployed the entire application. Eden Circle consumes the same authentication, authorization, company management, audit logging, and event bridging packages that our AI workbench uses — all through the same ConnectRPC contract layer. The engineer wrote zero authentication code, zero RBAC code, and zero multi-tenancy code. They wrote messaging, conferencing, and presence logic. The platform, generated and governed through ConnectRPC, handled everything else, including Docker Compose configuration and Helm charts for Kubernetes deployment.

The Framework Investment Math: Does a ConnectRPC Platform Pay Off?

Every engineering leader eventually asks whether a framework investment pays for itself. Here is the arithmetic from our own build.

InvestmentTime
eden-platform-go (14 packages)~3 days
eden-platform-flutter (auth, company, nav)~1 day
eden-platform-api-dart (generated via ConnectRPC)~0 days (automated)
eden-ui-flutter (50+ widgets)~2 days
eden-cli (scaffolding, codegen, dev server)~1 day
Total framework investment~7 days
ProductWith frameworkEstimated withoutTime saved
AI workbench4 days~3-4 weeks~2-3 weeks
Eden Circle (communications)8 days~4-6 weeks~3-4 weeks
Eden Family (3 products)In progress~6-8 weeks eachProjected ~4-6 weeks each
Eden HealthIn progress~3-4 weeksProjected ~2-3 weeks
Eden BizIn progress~3-4 weeksProjected ~2-3 weeks

The framework cost seven days. The first product saved two to three weeks. The second saved three to four more. By the third product, the ConnectRPC-based platform had paid for itself several times over, since every subsequent product starts with authentication, multi-tenancy, RBAC, audit logging, and deployment infrastructure already working.

The Registry Pattern: Server-Driven UI Built on ConnectRPC

The registry pattern deserves specific attention because it solves a coordination problem that plagues multi-product platforms. In a traditional architecture, adding a module requires frontend changes: a new route, a new sidebar entry, new navigation guards. In our architecture, the backend registers its capabilities through the same ConnectRPC services that power everything else, and the frontend shell reads the registry to build the UI dynamically.

When Eden Circle's backend starts, it registers its navigation items, search scopes, and widget configurations with the platform registry. The Flutter shell reads these registrations and constructs the sidebar, search interface, and dashboard without any product-specific navigation code. Consequently, this pattern inverts the traditional dependency: instead of the frontend knowing about every module, the modules tell the frontend about themselves — the same principle behind plugin architectures in IDEs and CMS platforms, now applied to a ConnectRPC-powered SaaS ecosystem.

Why Teams Are Replacing REST and OpenAPI with This RPC Framework

REST plus OpenAPI has been the default choice for a decade, but it has a structural flaw: the specification and the implementation are two separate artifacts that must be kept in sync by hand. In contrast, ConnectRPC generates both the server contract and the client contract from the exact same file, so drift becomes a compile error rather than a production bug. For teams who have been burned by a stale OpenAPI spec, this single guarantee is often reason enough to migrate.

Above all, ConnectRPC does not ask you to abandon familiar tooling to get these benefits. Because it speaks plain HTTP and optional JSON, your existing load balancers, API gateways, logging tools, and browser dev tools all continue to work exactly as before. This is a notably different path from the one we took earlier in our own stack's history — we even flirted with a full switch to Ruby on Rails before ultimately moving to Go, a detour we documented in Part 3 of this series, where Rails almost won.


Frequently Asked Questions About ConnectRPC

What is ConnectRPC used for?

ConnectRPC is used to define, generate, and call type-safe APIs between a server and multiple clients — including web browsers, mobile apps, and other backend services — from a single Protocol Buffers definition.

Is ConnectRPC the same as gRPC?

No. ConnectRPC is wire-compatible with gRPC and gRPC-Web, so existing gRPC clients and servers can interoperate with it, but ConnectRPC adds native browser support and JSON debugging without requiring a proxy.

Does ConnectRPC work in web browsers without a proxy?

Yes. Because ConnectRPC runs over standard HTTP/1.1 and HTTP/2, browsers can call ConnectRPC services directly, eliminating the Envoy sidecar that gRPC-Web traditionally requires.

Can ConnectRPC replace REST APIs entirely?

For most internal and product APIs, yes. ConnectRPC provides everything REST typically offers — JSON support, standard HTTP semantics, browser compatibility — plus compile-time type safety that hand-written REST APIs cannot guarantee.

What languages does ConnectRPC support?

Official ConnectRPC implementations exist for Go, Swift, Kotlin, and TypeScript/Node, and because it is wire-compatible with gRPC, any gRPC-capable language can interoperate with a ConnectRPC service.

Is ConnectRPC free and open source?

Yes. ConnectRPC is fully open source and free to use, maintained by Buf, with no licensing fees for commercial or production use.


Conclusion: Why ConnectRPC Is the Glue That Holds a Modern Stack Together

This series began with a fork of LibreChat and traced a path through Python, Svelte, Ruby on Rails, Go, and Flutter. Each phase taught us something: monoliths are fine until they are not, framework lock-in is expensive, and developer ergonomics matter but runtime characteristics matter more. The final lesson, however, is about the glue — and ConnectRPC is that glue. It is not the Go backend or the Flutter frontend that makes our ecosystem move fast. It is the .proto files, the generated clients, and the ConnectRPC contract that ties every product together without drift, without a proxy, and without hand-written glue code. If you are choosing an RPC framework today, ConnectRPC removes the operational tax of gRPC-Web while keeping everything gRPC does well. Invest in the contract layer, and everything else follows.

Add to Preferred Sources
blog author avatar

Justin Donnaruma

Justin Donnaruma is the founder and Chief Innovation Officer of AOCyber, where he sets the technical direction for a product line built on one constraint: the customer pays, so the customer is never the product. He founded Don't Panic Consulting in 2016 — a managed service provider working with Fortune 500 companies, hedge funds and national brands, with zero customer churn across five years of operations — and founded AOCyber in 2025 to build AI-native, privacy-first platforms. He writes here about AI governance, the economics of "free" AI, and what actually holds up when a model reaches production.

Back to Blog
AOCyber

You don't have to be the product anymore. Building the next generation of applications.

© 2026 AOCyber. All rights reserved.