pbrs is a Protocol Buffers runtime and code generator with the Google
protobuf v4 application API. The workspace also includes pbrs-grpc for
gRPC over HTTP/2 and protobuf-tonic for using pbrs messages with tonic 0.14+.
Documentation · gRPC example · Benchmark results · Run benchmarks · Parity audit
Status: conformance is tested through Protocol Buffers Edition 2023. Edition 2024 generation supports a defined subset. The gRPC crates are previews; see the support policy for supported versions and deployment guidance. The benchmark results show measured improvements and remaining CPU, allocation and bulk losses. Each result names the source it tested; full performance and release qualification remain open. See implementation status for compatibility details.
If you use proto2 messages with required children or MessageSet, regenerate bindings to get the merge and MessageSet fixes. Contributors should start with what to work on next.
Regenerate bindings to let lazy child getters reuse earlier wire validation.
Applications that read or mutate nested trees can also select
Config::owned_message_fields(true).
The default lazy profile supports partial reads and forwarding unchanged
messages. See the current measurements and tradeoffs.
- Google protobuf v4 API: generated types use
Parse,Serialize,Clear,proto!,ProtoStr,RepeatedView, andDynamicMessage. - Recorded conformance: Google's
conformance_test_runnerv35.1 passes 5,631 binary + JSON cases and 909 text cases with no unexpected results. - Formats and reflection: proto2, proto3, Edition 2023, well-known types (WKT), dynamic reflection, JSON, and text format.
- Storage: small-string optimization, zero-allocation empty collections, lazy materialization after wire validation, and specialized packed-scalar handling are built into the runtime.
pbrs is an application API alternative, not a drop-in replacement for
official generated internals or prost::Message. See the
upb comparison and implementation status for
the tested boundaries.
This quick start generates Rust from proto/person.proto during your Cargo
build. Direct .proto generation requires protoc on your PATH; see
code generation options if you want checked-in
descriptors instead.
-
Add
pbrsas both a runtime and build dependency:[dependencies] pbrs = "0.2" [build-dependencies] pbrs = "0.2"
-
Add a proto file at
proto/person.proto:syntax = "proto3"; package tutorial; message Person { string name = 1; int32 id = 2; string email = 3; repeated string phones = 4; }
-
Generate Rust in
build.rs:fn main() -> Result<(), Box<dyn std::error::Error>> { pbrs::codegen::compile_protos(&["proto/person.proto"], &["proto"])?; Ok(()) }
-
Include and use the generated type:
use pbrs::prelude::*; include!(concat!(env!("OUT_DIR"), "/person.rs")); fn main() -> Result<(), Box<dyn std::error::Error>> { let mut person = Person::new(); person.set_name("Ada Lovelace"); person.set_id(42); person.set_email("ada@example.com"); person.phones_mut().push("555-0100"); let bytes: Vec<u8> = person.serialize()?; let decoded = Person::parse(&bytes)?; assert_eq!(decoded.name(), "Ada Lovelace"); assert_eq!(decoded.id(), 42); println!("Parsed: {} (ID: {})", decoded.name(), decoded.id()); Ok(()) }
For protos that define services, compile_protos emits native pbrs-grpc
stubs by default. tonic users must opt in with
Config::emit_tonic_stubs(true).
| Need | Use | Published | Checkout candidate |
|---|---|---|---|
| Protocol Buffers messages, reflection, JSON/text, or code generation | pbrs |
0.2.0 |
0.2.1 (unreleased) |
| Native gRPC client and server | pbrs-grpc |
0.1.0-alpha.2 (published) |
0.1.0-alpha.3 (unreleased preview) |
tonic 0.14+ with pbrs messages |
protobuf-tonic |
0.1.0-alpha.2 (published) |
0.1.0-alpha.3 (unreleased preview) |
| Runnable service with health and reflection | examples/greeter |
— | Example |
The installation examples use published versions. Checkout candidates and newer APIs are not available from crates.io until released.
Generating directly from .proto files needs protoc. Generating from a
previously compiled descriptor set does not run protoc during the application
build.
| Task | Needs protoc? |
Notes |
|---|---|---|
Build the core pbrs crate |
No | The crate uses a bundled FileDescriptorSet. |
Build pbrs-grpc and protobuf-tonic (0.1.0-alpha.2 and later, or this checkout) |
No | They build from checked descriptor sets. |
Build the older pbrs-grpc / protobuf-tonic 0.1.0-alpha.1 crates |
Yes | Those alphas predate the checked-descriptor change. |
Run compile_protos or protoc-gen-pbrs on application .proto files |
Yes | protoc must be on PATH. |
Run Config::compile_descriptor_set from a checked descriptor set |
No during the app build | Creating or updating the descriptor set still needs protoc. |
There is no enforced universal protoc version; see the
support matrix.
Use this when your build environment has protoc available:
fn main() -> Result<(), Box<dyn std::error::Error>> {
pbrs::codegen::compile_protos(&["proto/person.proto"], &["proto"])?;
Ok(())
}Then include the generated file in src/lib.rs or src/main.rs:
include!(concat!(env!("OUT_DIR"), "/person.rs"));Use this when you want application builds to avoid running protoc. First
create and check in a descriptor set with imports included:
protoc -I proto --include_imports --descriptor_set_out=proto/person.fds proto/person.protoThen compile from that descriptor set:
fn main() -> Result<(), Box<dyn std::error::Error>> {
pbrs::codegen::Config::new()
.out_dir(std::env::var("OUT_DIR")?)
.compile_descriptor_set("proto/person.fds", &["person.proto"], &["proto"])?;
Ok(())
}Descriptor targets use include-relative names such as person.proto. The
descriptor and available source imports are tracked for rebuilds. See the
codegen guide for native stubs, tonic stubs, and
messages-only generation.
Against this checkout, a consumer using a checked descriptor set can cold-build
messages, native stubs, and tonic stubs without protoc on its build PATH.
The older 0.1.0-alpha.1 adapter archives still require it.
Install or build the plugin binary:
cargo install --path . --bin protoc-gen-pbrsRun protoc with the --pbrs_out flag:
protoc --pbrs_out=./gen --proto_path=./proto ./proto/hello.protoOr use the helper script:
./scripts/gen.sh -I proto -o gen proto/your.proto| Stack | Choose it when | Read more |
|---|---|---|
pbrs-grpc native kernel |
You want the native gRPC client and server. | gRPC guide, pbrs-grpc/README.md |
protobuf-tonic adapter |
You already use tonic 0.14+ and can use regenerated pbrs stubs instead of prost messages. Middleware must accept those message traits. |
protobuf-tonic/README.md |
For a complete service with generated stubs, health checking, and server
reflection, see examples/greeter.
The table lists minimum Rust versions and configured CI checks. Actual
compiler versions and results are recorded in the evidence guide.
Releases follow the release guide; pushes to main do not publish crates.
The maintained crates and tools use Rust language Edition 2024, available from rustc 1.85. Frozen reference/comparator and discarded-experiment manifests keep their original edition for reproducibility. This is independent of Protocol Buffers Edition 2024.
| Crate | Declared MSRV | CI checks | protoc |
Stub default |
|---|---|---|---|---|
pbrs |
1.85 | msrv-core 1.85 --lib, stable Linux + macOS |
Not required to build the crate (bundled FileDescriptorSet). Required for compile_protos / protoc-gen-pbrs. |
Messages; .proto service blocks emit native pbrs-grpc stubs |
pbrs-grpc |
1.85 | msrv-core 1.85 --lib and stalled-upload checks, stable Linux + macOS |
Current source builds from checked FileDescriptorSets. Regenerating descriptors or compiling application .proto requires protoc; the older 0.1.0-alpha.1 release also requires it to build. |
Native kernel (compile_protos default) |
protobuf-tonic |
1.88 | msrv-tonic 1.88 |
Current source builds from the checked FileDescriptorSet. Direct .proto compilation requires protoc; the older 0.1.0-alpha.1 release also requires it to build. |
Call Config::emit_tonic_stubs(true); not a prost::Message drop-in |
examples/greeter |
1.85 | Stable Linux (--workspace) + macOS onboarding |
Required | Native kernel default |
Untested / unsupported (not a support commitment):
- tonic 0.12 and 0.13 are unsupported.
- Protocol Buffers Edition 2024 has descriptor and generated-consumer coverage for a defined subset; complete conformance beyond Edition 2023 is not qualified.
- Windows CI is untested.
The benchmark report is the short results page: codec, message shapes, gRPC vs tonic, and gRPC vs grpc-go. Each section names its host and what was compared. The roadmap scorecard tracks the remaining comparisons.
For large payloads and copy behavior, also see Large payloads / zero-copy.
pbrs is tested against Google's official protobuf test suite:
| Suite | Recorded result | Scope |
|---|---|---|
Official conformance_test_runner v35.1 required tests (×2) |
5,631 binary + JSON, 0 unexpected failures | Pinned runner through Edition 2023 |
| Text format tests | 909 text tests, 0 unexpected failures | Pinned runner through Edition 2023 |
Recommended tests (--enforce_recommended) |
Passed with 0 unexpected failures | Does not imply every upstream suite |
The separate rust/test/shared coverage
lists its exclusions. The enum-map repair
and closed-enum tests record the later
compatibility runs.
Run the conformance suite locally:
./scripts/fetch-protobuf.sh
./scripts/conformance.shThe documentation map helps you choose a guide.
For task status, use python3 scripts/plan-status.py --ready; for API details,
run cargo doc --workspace --no-deps --open.
| Topic | Start here |
|---|---|
| Architecture and crate boundaries | Architecture overview |
| Runtime design and storage choices | Design and internals |
| API and representation differences from Google's C-based upb kernel | Relative to upb |
| Measurements and known losses | Benchmarks |
| Large payloads and copy behavior | Large payloads / zero-copy |
| Supported features and conformance breakdown | Implementation status |
Native pbrs-grpc services |
Native gRPC kernel guide |
| Code generation, RPC shapes, interceptors, and operations recipes | Task guides and recipes |
| tonic 0.14+ integration | Tonic adapter guide |
Toolchain and protoc requirements |
Support matrix |
| Publishing policy | Release policy |
| Roadmap and remaining work | Implementation plan and scorecard |
| Next contribution and audit findings | Execution queue, repository audit, task contracts |
| gRPC performance work | Performance plan and task cards |
| Adopting pbrs in existing prost/tonic systems | Adoption program |
| Every-cell comparison against tonic and prost | Workload comparison plan |
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option.