# Start Here: What This Repo Is & Where to Begin

> What connect-rust is, the three-crate layout (connectrpc / connectrpc-codegen / connectrpc-build), the fastest read order for a new contributor, key vocabulary (ConnectRPC, buffa, Tower service, Spec, StreamType), and which files to open first.

- Repository: anthropics/connect-rust
- GitHub: https://github.com/anthropics/connect-rust
- Human wiki: https://grok-wiki.com/public/wiki/anthropics-connect-rust-abe117693c52
- Complete Markdown: https://grok-wiki.com/public/wiki/anthropics-connect-rust-abe117693c52/llms-full.txt

## Source Files

- `README.md`
- `Cargo.toml`
- `connectrpc/src/lib.rs`
- `docs/guide.md`
- `CONTRIBUTING.md`

---

<details>
<summary>Relevant source files</summary>
The following files were used as context for generating this wiki page:

- [README.md](README.md)
- [Cargo.toml](Cargo.toml)
- [connectrpc/src/lib.rs](connectrpc/src/lib.rs)
- [connectrpc/src/spec.rs](connectrpc/src/spec.rs)
- [connectrpc/src/interceptor.rs](connectrpc/src/interceptor.rs)
- [connectrpc/src/payload.rs](connectrpc/src/payload.rs)
- [connectrpc-codegen/src/lib.rs](connectrpc-codegen/src/lib.rs)
- [connectrpc-build/src/lib.rs](connectrpc-build/src/lib.rs)
- [docs/guide.md](docs/guide.md)
- [CONTRIBUTING.md](CONTRIBUTING.md)
</details>

# Start Here: What This Repo Is & Where to Begin

`connect-rust` is a [Tower](https://docs.rs/tower/latest/tower/)-based Rust implementation of the [ConnectRPC](https://connectrpc.com/) protocol. It lets you build servers and clients that speak Connect, gRPC, and gRPC-Web over HTTP — using the same transport-agnostic `tower::Service` abstraction the broader Rust web ecosystem relies on. The library passes 3,600 server and 6,872 client conformance tests across all three protocols and is production-quality even at its pre-1.0 version.

This page orients you to the repository's structure, key terms, and the fastest reading path before you touch code. It answers the question every new contributor has: *where do I start?*

---

## The Three-Crate Layout

The workspace (`Cargo.toml`) publishes three crates that work together:

```text
connect-rust/
├── connectrpc/         ← runtime library (Tower service, codecs, compression, interceptors)
├── connectrpc-codegen/ ← code generation library + protoc-gen-connect-rust binary
└── connectrpc-build/   ← build.rs integration (wraps codegen for use at build time)
```

Sources: [Cargo.toml:1-11](), [docs/guide.md:27-33]()

### `connectrpc` — The Runtime

This is the crate your application code depends on at runtime. It provides:

- **`ConnectRpcService`** — the core `tower::Service` that receives HTTP requests and dispatches them to registered handlers.
- **`Router`** — collects RPC handler registrations; call `.register()` on your service impl to populate it.
- **`Handler` / `ViewHandler` / streaming variants** — async handler traits your service structs implement. The `View`-prefixed variants return zero-copy `buffa` view types directly from the request buffer.
- **`Interceptor` / `Next` / `NextStream`** — typed RPC middleware: runs after envelope decoding but before handler invocation; has access to `Spec`, headers, deadline, and a lazily decoded `Payload`.
- **`Spec` / `StreamType`** — static per-method metadata (see [Key Vocabulary](#key-vocabulary) below).
- **`Payload` / `AnyMessage`** — type-erased, lazily-decoded message bodies used by interceptors.
- **`client` module** — `HttpClient` and `Http2Connection` transports for generated clients (enabled by the `client` feature flag).
- **`Server`** — a built-in standalone hyper server (enabled by the `server` feature).

Sources: [connectrpc/src/lib.rs:1-200](), [connectrpc/src/lib.rs:220-315]()

### `connectrpc-codegen` — Code Generation Library and Plugin

This crate lives in two roles simultaneously:

1. **Library** (`codegen::generate_files` / `codegen::generate_services`): drives code generation from compiled proto descriptors. Used internally by `connectrpc-build` and the plugin binary.
2. **Binary** (`protoc-gen-connect-rust`): a `protoc` / `buf` plugin that generates service traits, client structs, and `Spec` constants from `.proto` files. Install it with `cargo install --locked connectrpc-codegen` or download a release binary.

Two generation modes exist:
- **Unified** (`generate_files`): message types + service stubs in one file per proto, with `super::`-relative paths. Used by `connectrpc-build`.
- **Service-stubs only** (`generate_services`): references message types via configurable absolute paths (e.g. `crate::proto::greet::v1::GreetRequest`). Used by the `protoc-gen-connect-rust` plugin when paired with `buf generate`.

Sources: [connectrpc-codegen/src/lib.rs:1-43]()

### `connectrpc-build` — Build-time Integration

A `build.rs` helper that shells out to `protoc` (or `buf`, or reads a pre-compiled `FileDescriptorSet`) to obtain descriptors, then calls `connectrpc-codegen` to write Rust code into `$OUT_DIR`. After adding this as a build-dependency, you reference the output with `connectrpc::include_generated!()`.

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

Sources: [connectrpc-build/src/lib.rs:1-54]()

---

## Key Vocabulary

New contributors encounter a handful of terms that don't resolve obviously from the crate names alone.

| Term | What it means |
|---|---|
| **ConnectRPC** | The [protocol specification](https://connectrpc.com/docs/protocol/) that defines how unary and streaming RPC calls are framed over HTTP/1.1 and HTTP/2. Connect is one of three protocols this library speaks; the other two are gRPC and gRPC-Web. |
| **buffa** | The companion protobuf runtime from `github.com/anthropics/buffa`. Replaces prost. Its key feature is *view types*: zero-copy structs that borrow string and bytes fields directly from the incoming request buffer, avoiding per-field allocations. `buffa = { version = "0.6" }` is a workspace dependency. |
| **Tower service** | `tower::Service<Request, Response = Response, Error = Infallible>`. `ConnectRpcService` implements this trait, making it composable with any Tower-compatible HTTP framework (Axum, Hyper) or middleware stack. |
| **`Spec`** | A `Copy`, `'static` struct emitted as a `const` by codegen for each RPC method. Carries the fully-qualified procedure path (`"/pkg.Service/Method"`), its `StreamType`, its idempotency level, and whether it lives on the client or server side (`SpecOrigin`). Interceptors read `Spec` to label tracing spans or route behavior without re-parsing the URL. |
| **`StreamType`** | An enum with four variants: `Unary`, `ClientStream`, `ServerStream`, `BidiStream`. Records how many messages flow in each direction on a given RPC. The connect-go naming is used so cross-runtime interceptor logic ports cleanly. |
| **`Payload`** | A type-erased, lazily-decoded request/response body. Holds wire bytes as a reference-counted `Bytes` and decodes to the typed message on first access. Interceptors that never inspect message content pay zero decode cost. |
| **`Interceptor`** | A typed RPC middleware trait. Unlike a raw Tower layer, an interceptor runs *after* envelope decoding and header parsing — it sees the already-understood `Spec` and `Payload`, not raw bytes. Registered via `ConnectRpcService::with_interceptor`. |
| **`MethodKind` / `MethodDescriptor`** | Internal routing-table equivalents of `StreamType`; used by `Router` when registering handlers. `StreamType` is the interceptor-facing version; prefer it in interceptor code. |

Sources: [connectrpc/src/spec.rs:1-60](), [connectrpc/src/interceptor.rs:1-42](), [connectrpc/src/payload.rs:1-15]()

---

## How the Three Pieces Fit Together

```text
  .proto files
       │
       ▼
┌─────────────────────────────────────┐
│  Code Generation (pick one path)    │
│                                     │
│  Option A: buf generate             │
│    protoc-gen-buffa   → message types (src/generated/buffa/)
│    protoc-gen-connect-rust → service stubs (src/generated/connect/)
│                                     │
│  Option B: build.rs                 │
│    connectrpc-build::Config::compile()
│    → unified .rs into $OUT_DIR/     │
└─────────────────────────────────────┘
       │
       ▼ (generated output)
 FooServiceServer<T>   FooServiceClient<T>   const SPEC_FOO: Spec
       │                       │
       ▼                       ▼
┌──────────────┐    ┌──────────────────────┐
│  connectrpc  │    │  connectrpc client   │
│  Router      │    │  HttpClient /        │
│  Dispatcher  │    │  Http2Connection     │
│  ConnectRpc  │    └──────────────────────┘
│  Service     │
│  (tower::    │
│   Service)   │
└──────────────┘
       │
       ▼
  Axum / Hyper / standalone Server
```

Sources: [README.md:23-30](), [connectrpc/src/lib.rs:62-73]()

---

## The Two Codegen Workflows

### Option A — `buf generate` (checked-in code)

Run `buf generate` with two plugins: `protoc-gen-buffa` (message types) and `protoc-gen-connect-rust` (service stubs). Each produces its own output directory. The `buffa_module=crate::proto` option tells the service-stub generator where the buffa output is mounted in your crate, so it emits absolute paths like `crate::proto::greet::v1::GreetRequest`.

Use this when you want generated code checked into source control and reviewed in PRs.

### Option B — `connectrpc-build` (build-time generation)

Add `connectrpc-build` as a build dependency and call it from `build.rs`. Message types and service stubs appear in one file per proto under `$OUT_DIR`, referenced via `connectrpc::include_generated!()`. No plugin binaries on `PATH` at build time (only `protoc` or `buf`).

Use this for simpler projects or when you don't want generated code in git.

Sources: [README.md:57-179](), [connectrpc-build/src/lib.rs:1-33]()

---

## Feature Flags

The runtime is gated so you only pay for what you use. Defaults include compression; networking is opt-in.

| Feature | Default | What it adds |
|---|---|---|
| `gzip` | yes | Gzip compression (flate2) |
| `zstd` | yes | Zstandard compression |
| `streaming` | yes | Streaming compression (async-compression) |
| `client` | **no** | HTTP client transports (plaintext) |
| `client-tls` | **no** | TLS for client transports |
| `server` | **no** | Built-in hyper `Server` |
| `server-tls` | **no** | TLS for the built-in server |
| `tls` | **no** | Convenience alias: both server-tls + client-tls |
| `axum` | **no** | Axum integration (`into_axum_service`) |

The core crate also compiles for `wasm32-unknown-unknown`. Client transports, server, TLS, and `zstd` require native targets and are excluded on wasm.

Sources: [connectrpc/src/lib.rs:139-152](), [README.md:307-340]()

---

## Fastest Read Order for a New Contributor

Work through these in order. Each step builds on the previous and should take 5–15 minutes.

### Step 1 — Orient yourself (15 min)

| File | What to notice |
|---|---|
| [`README.md`](README.md) | The quick-start shows the full unary server + Axum loop. Read the feature-flag table and the protocol support matrix. |
| [`CONTRIBUTING.md`](CONTRIBUTING.md) | Prerequisites (Rust 1.88, protoc v27+, buf, task), change-size limit (≤250 net lines), test-coverage expectations, and the `task` command inventory. |
| [`Cargo.toml`](Cargo.toml) | The workspace member list, the `buffa` dependency version floor, and the compression / TLS / framework dependency choices. |

### Step 2 — The runtime entry point (20 min)

| File | What to notice |
|---|---|
| [`connectrpc/src/lib.rs`](connectrpc/src/lib.rs) | Module inventory and the full re-export surface. Every public symbol the library exposes is listed here. The `__codegen` hidden module is what generated code calls. |
| [`connectrpc/src/spec.rs`](connectrpc/src/spec.rs) | `Spec`, `StreamType`, `IdempotencyLevel`, `SpecOrigin`. These four types are the lingua franca of interceptors and generated code; understanding them unlocks the rest. |

### Step 3 — Interceptors and Payload (15 min)

| File | What to notice |
|---|---|
| [`connectrpc/src/interceptor.rs`](connectrpc/src/interceptor.rs) | The `Interceptor` trait and how unary vs streaming interceptors differ. Notice the ASCII diagram of interception order. |
| [`connectrpc/src/payload.rs`](connectrpc/src/payload.rs) | Why `Payload` is lazily decoded: most interceptors never look inside the message. |

### Step 4 — Code generation (15 min)

| File | What to notice |
|---|---|
| [`connectrpc-codegen/src/lib.rs`](connectrpc-codegen/src/lib.rs) | The two generation modes (`generate_files` vs `generate_services`) and when each is used. |
| [`connectrpc-build/src/lib.rs`](connectrpc-build/src/lib.rs) | The `Config` builder: how `DescriptorSource` (protoc / buf / precompiled) is selected at build time. |

### Step 5 — The user guide and examples (30 min)

| File | What to notice |
|---|---|
| [`docs/guide.md`](docs/guide.md) | Long-form coverage of every topic: installation, codegen, streaming, interceptors, Tower middleware, TLS, errors, compression. Read the sections that match your task. |
| [`examples/`](examples/) | Runnable examples: `eliza` (TLS), `middleware` (Tower auth layer), `streaming-tour` (all four RPC types side by side), `wasm-client` (Fetch transport), `multiservice` (multi-service router). |

---

## Files to Open First

If you are fixing a bug or adding a feature, these files are most likely to be involved:

```text
connectrpc/src/
├── lib.rs          ← re-export surface; start here to find any symbol
├── spec.rs         ← Spec, StreamType — shared by codegen and runtime
├── interceptor.rs  ← Interceptor trait; the RPC middleware API
├── handler.rs      ← Handler traits your service structs implement
├── router.rs       ← MethodKind, Router — the routing table
├── service.rs      ← ConnectRpcService — the tower::Service impl
├── payload.rs      ← Payload, AnyMessage — lazy decode
├── codec.rs        ← ProtoCodec, JsonCodec — encode/decode
├── compression.rs  ← CompressionProvider, CompressionRegistry
└── client/         ← HttpClient, Http2Connection, CallOptions

connectrpc-codegen/src/
├── lib.rs          ← two generation entry points
└── codegen/        ← quote!-based code emitters

connectrpc-build/src/
└── lib.rs          ← Config builder; DescriptorSource variants
```

---

## What the Workspace Also Contains

Beyond the three published crates, the workspace includes:

| Path | Purpose |
|---|---|
| `conformance/` | Conformance test runner binaries (server and client) that talk to the upstream ConnectRPC conformance suite |
| `examples/eliza/`, `examples/streaming-tour/`, etc. | Runnable end-to-end examples; see `docs/guide.md` for a tour |
| `tests/streaming` | In-workspace integration consumer of `connectrpc-build` — the canonical test of the build-time codegen path |
| `benches/rpc/` | Criterion benchmarks; `task bench:cross:quick` runs them |
| `docs/specs/` | Local copies of the Connect, gRPC, and gRPC-Web protocol specs; fetch with `task specs:fetch` |

Sources: [Cargo.toml:2](), [CONTRIBUTING.md:1-120]()

---

## Summary

`connect-rust` is a three-crate workspace: `connectrpc` (the Tower-based runtime), `connectrpc-codegen` (the `protoc-gen-connect-rust` plugin library and binary), and `connectrpc-build` (the `build.rs` wrapper). The vocabulary that glues them together is small: `Spec` describes a method statically, `StreamType` describes its message shape, `Payload` defers decode cost to interceptors that actually need it, and `buffa` provides the zero-copy protobuf message types. Start with `connectrpc/src/lib.rs` to see every public symbol in one place, then read `connectrpc/src/spec.rs` and `docs/guide.md` before touching anything else.

Sources: [connectrpc/src/lib.rs:1-75](), [connectrpc/src/spec.rs:1-40]()
