COOLJAPAN
← All posts

OxiRPC 0.2.0 — Pure-Rust gRPC, the NoFFI Replacement for protoc, OpenSSL, and ring

OxiRPC is the COOLJAPAN Pure-Rust gRPC stack: tonic-style gRPC over HTTP/2 whose proto codegen, TLS, and compression are 100% Pure Rust. No protoc binary, no OpenSSL, no ring by default — codegen via OxiProto, TLS via OxiTLS, gzip/zstd via OxiARC. Part of the NoFFI sovereign Rust stack.

release oxirpc pure-rust cooljapan noffi grpc rpc networking protobuf

gRPC in Rust no longer needs a C++ compiler to build, or a C crypto library to secure.

Today we’re releasing OxiRPC 0.2.0 — the COOLJAPAN Pure-Rust gRPC stack: a production-ready facade over tonic 0.14 that wires its proto codegen, TLS, and message compression entirely out of the oxi* ecosystem.

No protoc. No OpenSSL. No ring by default. No FFI, no -sys crates, no apt-get install protobuf-compiler. The default feature closure of OxiRPC is 100% Pure Rust and FFI-free — and so is the entire --all-features closure of the facade.

Why OxiRPC

gRPC is the lingua franca of service-to-service communication, but standing up a gRPC service in Rust has always dragged in a native toolchain. You need the protoc C++ compiler at build time to turn .proto files into code. You need a TLS backend — almost always OpenSSL or ring — to secure the wire. And the moment you turn on message compression, you pull in flate2 or the zstd C crate. Three separate FFI dependencies, three separate ways for a clean cargo build to fail inside a slim container.

OxiRPC removes all three. It keeps tonic’s familiar gRPC-over-HTTP/2 transport and its ergonomic builder API, then replaces every native edge underneath:

Old dependencyReplaced by
protoc binaryOxiProto (oxiproto-build + protox)
openssl-sysOxiTLS (rustls + rustls-rustcrypto)
ringOxiTLS pure_provider()
flate2OxiARC oxiarc-deflate
zstd C crateOxiARC oxiarc-zstd

Run cargo tree -p oxirpc --edges normal on default features or --all-features and you will find zero occurrences of protoc, openssl, openssl-sys, ring, aws-lc-sys, native-tls, flate2, or the zstd C crate. That is the whole point: a fresh container builds, and the binary speaks gRPC, with nothing native in the way.

What we built

OxiRPC is a nine-crate workspace, exported through a single oxirpc facade so you can depend on one crate and reach everything.

1. The facade and core (oxirpc, oxirpc-core) oxirpc re-exports the whole stack under one dependency. oxirpc-core holds the foundation: error and status types, metadata, timeouts, the encoding layer, the wire layer, and TLS plumbing.

2. Build-time codegen with no protoc (oxirpc-build) Drop oxirpc-build into [build-dependencies] and call compile_protos from your build.rs. It compiles .proto files via oxiproto-build + protox — pure Rust, no protoc binary to install or pin. Each proto set’s descriptor is cached under $OUT_DIR/.oxirpc-cache/fds-<hash>.bin, keyed by a stable hash of the sorted input paths, so independent compile_to_fds calls sharing one $OUT_DIR never collide.

3. The wire layer (oxirpc-core::wire) A native HTTP/2 gRPC wire implementation: FrameEncoder/FrameDecoder as tokio-util codecs, GrpcRequestHeaders/GrpcResponseHeaders, gRPC status-trailer encoding with percent-encoding, a compression-aware MessagePipeline, and a Deadline + timeout codec. The bidirectional driver (drive_bidi / drive_bidi_with_encoding) is truly streaming — built on an incremental FrameDecoder, it can deliver response N before request N+1.

4. Pure-Rust TLS (oxirpc-core::tls, oxirpc-client::tls_connector) PureRustTlsConnector wires rustls together with OxiTLS’s pure_provider() into tonic-transport’s connect_with_connector. The result is end-to-end Pure-Rust TLS on both client and server — no ring, no OpenSSL — without forking tonic.

5. Pure-Rust compression (oxirpc-core::encoding) CompressionEncoding (Identity / Gzip / Zstd) is backed by oxiarc-deflate and oxiarc-zstd, with wire-level FLAG_COMPRESSED framing in the gRPC-Web codec. No flate2, no zstd C crate on any feature edge.

6. Client and server (oxirpc-client, oxirpc-server) The client provides a ClientBuilder, a channel pool, load balancing (round-robin, weighted, pick-first), resilience, and xDS/ADS support. The server provides a ServerBuilder with routing, a native service registry, compression layers, and TLS. A native HTTP/2 server (NativeServiceRegistry) adds streaming bidi handling.

7. The protocol extras (oxirpc-reflect, oxirpc-health, oxirpc-web) oxirpc-reflect implements gRPC server reflection v1 + v1alpha (with an optional oxiproto-reflect DescriptorPool backend). oxirpc-health implements the gRPC health-checking protocol v1, with per-service status mirroring, bulk set_all_serving / set_all_not_serving, and Watch streaming. oxirpc-web provides a gRPC-Web bridge — a GrpcWebLayer that wraps any tonic Router, handling binary and base64 text mode, compression-aware data frames, trailer-frame synthesis, and a CorsPolicy with wildcard, per-origin, and allow_credentials modes.

Getting Started

Add OxiRPC as a runtime dependency and the build helper as a build dependency:

# Cargo.toml
[dependencies]
oxirpc = { version = "0.2", features = ["client", "server", "tls", "health"] }

[build-dependencies]
oxirpc-build = "0.2"

Compile your protos at build time — no protoc required:

// build.rs
fn main() -> Result<(), Box<dyn std::error::Error>> {
    oxirpc_build::compile_protos(&["proto/greeter.proto"], &["proto/"])?;
    Ok(())
}

Stand up a server with the familiar builder API:

// Server
use oxirpc::{ServerBuilder, OxiRpcError};
use std::net::SocketAddr;

#[tokio::main]
async fn main() -> Result<(), OxiRpcError> {
    let addr: SocketAddr = "[::1]:50051".parse().expect("valid addr");
    ServerBuilder::new()
        .add_service(my_service())
        .serve(addr)
        .await
}

And connect a client:

// Client
use oxirpc::ClientBuilder;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let channel = ClientBuilder::new("http://[::1]:50051")
        .connect()
        .await?;
    // let client = MyServiceClient::new(channel);
    Ok(())
}

To turn everything on at once:

cargo add oxirpc --features "client,server,tls,health,reflect,web,gzip,zstd"

Highlights

Tips

Part of the COOLJAPAN ecosystem

OxiRPC is one piece of NoFFI — the COOLJAPAN initiative to replace every C/C++/Fortran/-sys FFI dependency in the Rust ecosystem with a clean, memory-safe, 100% Pure Rust implementation. OxiRPC sits at the networking layer and stitches three siblings together: it depends on OxiProto for descriptor parsing (replacing protoc), OxiTLS for its crypto provider and certificate types (replacing OpenSSL and ring), and OxiARC for compression (replacing flate2 and zstd-sys).

It is, in turn, the gRPC backbone for the rest of the stack — powering oxirouter (gateway ingress and service-to-service), oxigenai (LLM inference server API), oxigdal-cluster (geospatial distributed coordination), oxionnx (model serving), and oxirs (SPARQL-over-gRPC).

Repository: https://github.com/cool-japan/oxirpc

Star the repo if you want gRPC in Rust that builds in a bare container and ships as a single static binary.

Pure Rust gRPC — sovereign, safe, and FFI-free.

KitaSan at COOLJAPAN OÜ June 23, 2026

↑ Back to all posts