# ADR-006: SDK-First Adoption — Native QUIC + Cap'n Proto, No REST Gateway ## Status Accepted (supersedes earlier REST gateway proposal) ## Context quicproquo uses QUIC + Cap'n Proto RPC as its native protocol. This combination delivers zero-copy serialization, multiplexed streams, and sub-RTT connection establishment — ideal for high-performance clients. Cap'n Proto has limited language support compared to Protocol Buffers or JSON. Adding an HTTP/JSON REST gateway was considered to lower the barrier to entry. However, this would: 1. **Contradict the project identity.** The name is literally **quic**n**proto**chat. An HTTP gateway undermines the protocol-native philosophy. 2. **Add base64 overhead (~33%)** for binary payloads (MLS ciphertext, key packages) that are already optimal in Cap'n Proto's wire format. 3. **Create a second code path** to maintain, test, and secure. 4. **Lose QUIC transport benefits** (0-RTT, multiplexing, congestion control) for clients that use the HTTP path. ## Decision **No REST/HTTP gateway.** Instead, invest in native QUIC + Cap'n Proto SDKs for every viable language, plus WASM/FFI for the crypto layer. The `.capnp` schema files ARE the interface definition — they serve the same role as an OpenAPI spec, but for the native protocol. ### SDK strategy | Language | QUIC | Cap'n Proto | Approach | |----------|------|-------------|----------| | **Rust** | quinn | capnp-rpc | Existing reference client | | **Go** | quic-go | go-capnp | Native SDK, high confidence | | **Python** | aioquic | pycapnp | Native QUIC, manual RPC framing | | **C/C++** | msquic/ngtcp2 | capnproto | Reference impl, full RPC | | **Browser** | WebTransport | WASM bridge | QUIC transport via HTTP/3 | ### Browser access via WebTransport Browsers cannot open raw QUIC connections, but they can use **WebTransport** — which runs over HTTP/3 (which runs over QUIC). The server adds a WebTransport listener alongside the Cap'n Proto QUIC listener. Cap'n Proto RPC is framed over WebTransport bidirectional streams, identical to the native path. ``` Browser → WebTransport (HTTP/3 over QUIC) → Cap'n Proto RPC → Server Native → QUIC → Cap'n Proto RPC → Server ``` Both paths use QUIC transport. The project name stays honest. ### Crypto layer distribution MLS encryption/decryption must happen client-side. The `quicproquo-core` crate is compiled to: - **WASM** — for browsers, Node.js, Deno - **C FFI** (`libquicproquo`) — for Swift, Kotlin, Python, Go (via cgo) - **Native Rust** — for Rust clients (existing) ### Why not REST? 1. **Protocol purity.** One protocol, one code path, one mental model. 2. **No serialization tax.** No base64, no JSON parsing, no HTTP headers. 3. **QUIC everywhere.** WebTransport gives browsers QUIC access without HTTP semantics leaking into the protocol. 4. **Schema-driven.** `.capnp` files generate type-safe stubs in every supported language — the same developer experience as protobuf/gRPC. ### Why not gRPC? 1. **We already have Cap'n Proto** with zero-copy deserialization. 2. Adding protobuf would mean three serialization formats in one project. 3. Cap'n Proto's time-travel RPC (promise pipelining) is architecturally superior to gRPC's request-response model for chained operations. gRPC may be reconsidered for server-to-server federation (Phase 7.3). ## Consequences ### Positive - **Protocol coherence.** Every client speaks the same wire format. - **Performance.** No translation layer, no base64 overhead, no HTTP framing. - **Identity.** The project name accurately describes the protocol stack. - **Security.** One code path to audit, not two. - **WebTransport.** Browsers get native QUIC with the same RPC interface. ### Negative - **Higher SDK effort.** Each language needs a QUIC + Cap'n Proto integration, not just an HTTP client. - **Cap'n Proto ecosystem gaps.** JavaScript and Swift lack mature Cap'n Proto RPC libraries; these languages rely on WASM bridges. - **WebTransport maturity.** Browser support is good (Chrome, Edge, Firefox) but not universal; Safari support is emerging. ### Neutral - SDKs live in separate repositories (e.g., `quicproquo-go`, `quicproquo-py`) to avoid bloating the core workspace. - The C FFI crate (`quicproquo-ffi`) bundles both crypto and transport, so language bindings only need to call C functions. ## Related - [ADR-002: Cap'n Proto over MessagePack](adr-002-capnproto.md) — why Cap'n Proto was chosen - [ROADMAP Phase 3](../../../ROADMAP.md) — SDK implementation plan - [FUTURE-IMPROVEMENTS § 6.2](../../../docs/FUTURE-IMPROVEMENTS.md) — WebTransport research