Introduction
Twirp is an RPC framework created by Twitch that generates Go servers and clients from Protobuf service definitions. Unlike gRPC, Twirp uses standard HTTP/1.1 and works with any HTTP infrastructure without requiring HTTP/2 or special proxies. It supports both Protobuf binary and JSON encoding on the same endpoints.
What Twirp Does
- Generates type-safe Go server interfaces and client implementations from .proto files
- Serves RPCs over standard HTTP/1.1 POST requests with routing based on URL paths
- Supports both Protobuf binary and JSON content types on every endpoint automatically
- Provides hooks and interceptors for middleware like logging, auth, and metrics
- Works with any HTTP reverse proxy, load balancer, or CDN without special configuration
Architecture Overview
Twirp generates a Go interface matching each Protobuf service. The server implementation wraps this interface in an http.Handler that routes requests by URL path (/twirp/package.Service/Method). Content negotiation selects Protobuf or JSON based on the Content-Type header. The client is a simple HTTP client that serializes requests and deserializes responses. Errors use a structured format with codes that map to HTTP status codes.
Self-Hosting & Configuration
- Install the protoc-gen-twirp plugin and use it alongside protoc and protoc-gen-go
- Implement the generated interface and mount the handler on your HTTP server or mux
- Configure interceptors for cross-cutting concerns like authentication and request logging
- Use the generated client with any http.Client, including custom transports for retries or tracing
- Deploy behind standard load balancers like Nginx, HAProxy, or cloud ALBs without changes
Key Features
- No HTTP/2 or gRPC proxy dependency, working with plain HTTP/1.1 infrastructure
- Dual Protobuf and JSON support on every endpoint makes debugging easy with curl
- Structured error model with typed error codes, metadata, and HTTP status mapping
- Minimal code generation with no runtime reflection or service registration boilerplate
- Small library footprint with no external dependencies beyond the Go standard library
Comparison with Similar Tools
- gRPC-Go — full-featured RPC with streaming and HTTP/2, but requires HTTP/2-aware infrastructure
- ConnectRPC — modern gRPC-compatible framework that also supports HTTP/1.1, with broader language support
- net/http + JSON — no code generation overhead, but loses type safety and requires manual serialization
- Buf Connect — similar goals to Twirp with additional features like streaming and browser support
FAQ
Q: Does Twirp support streaming RPCs? A: No. Twirp only supports unary request-response RPCs. If you need streaming, consider gRPC or ConnectRPC.
Q: Can I use Twirp with languages other than Go? A: The official generator targets Go, but community generators exist for Python, Ruby, TypeScript, and others.
Q: Why choose Twirp over gRPC? A: Twirp is simpler to deploy because it uses HTTP/1.1 and works with any existing HTTP infrastructure. It is a good choice when you do not need streaming or bidirectional communication.
Q: How does error handling work? A: Twirp defines a set of error codes (not_found, internal, permission_denied, etc.) that map to HTTP status codes. Errors include a code, message, and optional metadata map.