Anthropic built connect-rust and has now contributed it to Connect, so Rust joins Go, Node.js, Web, Swift, Kotlin, Dart, and Python with an official Connect implementation.

What’s in it

  • The connectrpc crate: servers and clients that speak Connect, gRPC, and gRPC-Web.
  • Tower and Axum integration, plus a standalone Hyper server if you’d rather not bring a framework.
  • gRPC health checking and server reflection, in the connectrpc-health and connectrpc-reflection crates.
  • Buffa, a zero-copy Protobuf runtime with support for Editions and ProtoJSON.

What it looks like

The repository’s examples/eliza implements the classic ELIZA chatbot in Rust. Point the client at the local Rust server or at the hosted demo on https://demo.connectrpc.com.

Creating the client takes three lines:

let http = make_transport(&args, &base_uri)?;
let config = ClientConfig::new(base_uri);
let client = ElizaServiceClient::new(http, config);

ElizaServiceClient is generated from the service’s Protobuf schema — see below.

Introduce is server streaming, so Eliza sends a few sentences and the client prints each one as it arrives:

let mut intro = client
    .introduce(IntroduceRequest {
        name: name.to_owned(),
        ..Default::default()
    })
    .await?;
while let Some(msg) = intro.message().await? {
    println!("Eliza> {}", msg.view().sentence);
}

view() borrows the decoded message, so reading sentence doesn’t copy anything out of the response buffer. The full example adds the bidirectional Converse loop, the TLS and mTLS flags, and the server side of the same schema.

How it works

Tower is the de facto standard for middleware in async Rust: Axum, tonic, and the timeout, retry, tracing, and rate-limiting layers people already have in their stacks all build on it. connectrpc does too. The Connect router is a tower::Service, so it natively accepts any Tower layer and mounts directly into Tower-compatible HTTP frameworks. With Axum, the router’s .into_axum_service() hands off to Axum’s fallback_service, so Connect RPCs share a server with ordinary HTTP routes: health checks, static files, OAuth callbacks. That conversion comes from the axum feature, and the server feature bundles a standalone Hyper server if you don’t want a framework at all.

One server handles all three protocols and all four RPC types, so a Rust service can serve a browser over gRPC-Web and a gRPC client without running two stacks.

Message serialization comes from buffa, a Protobuf runtime Anthropic built alongside connect-rust. Buffa generates both owned message types and borrowed views, so string and bytes fields can point directly into the request buffer instead of allocating a new String or Vec<u8>. A handler that only reads a message works with borrowed &str and &[u8] fields; code that needs to keep the message around converts it to an owned value. Buffa also supports Protobuf Editions and ProtoJSON.

The implementation passes the complete Connect conformance suite across the three protocols, 3,600 server and 6,872 client tests. It’s still pre-1.0, so the API may shift during 0.x, but this isn’t a prototype: it’s already running in production at Anthropic. On a decode-heavy benchmark with string-heavy messages, it delivered about a third more throughput than tonic at high concurrency while spending much less CPU time in the allocator.

The client, server, TLS, and Axum pieces all sit behind feature flags, so you only compile what you use. The minimum supported Rust version is 1.88.

Code generation

There are three ways to generate Rust code.

Generated SDKs. If the schema lives on the BSR, cargo can fetch the generated code from the BSR’s cargo registry like any other dependency: one crate holds the Protobuf types, generated by Buffa, and another holds the Connect clients and service traits. Nothing to generate, nothing to check in.

# .cargo/config.toml
[registries.buf]
index = "sparse+https://buf.build/gen/cargo/"
credential-provider = "cargo:token"
$ cargo login --registry buf   # paste "Bearer <your BSR token>"
$ cargo add --registry buf \
    connectrpc_eliza_connectrpc_rust@^0.9.0-0 \
    connectrpc_eliza_anthropics_buffa@^0.9.1-0

That’s all it takes to get a working client for the hosted Eliza demo.

Generating code at build time. connectrpc-build runs the codegen from build.rs, with no plugin binaries to install and nothing generated to check in:

fn main() {
    connectrpc_build::Config::new()
        .files(&["greet/v1/greet.proto"])
        .use_buf()
        .include_file("_connectrpc.rs")
        .compile()
        .unwrap();
}

use_buf() compiles descriptors with the Buf CLI; without it, connectrpc-build shells out to protoc. Either way, one of the two has to be on your PATH.

Checked-in output. If you want the traditional buf generate flow, with either local or remote plugins, you can do that too. The project README has the details.

What the move means

Iain McGinniss and Drew Sacamano put Rust forward as an official implementation in RFC 007. The repository now lives in the connectrpc organization, so issues, pull requests, and releases all happen there, and Iain continues as maintainer. Buffa is a general-purpose Protobuf runtime rather than a Connect component, so it stays at anthropics/buffa.

Thanks

Thanks to Anthropic for contributing connect-rust to the Connect project, and especially to Iain McGinniss, who led its development. Both projects came together in about six weeks, with Claude Opus 4.6 doing most of the work under Iain’s direction.

Iain’s post, Zero-copy protobuf and ConnectRPC for Rust, goes much deeper into Buffa’s zero-copy approach, the Connect implementation, and the benchmark results.

To try it, start with the README or the user guide.