Introducing the Replane Rust SDK
Replane now has an official Rust SDK. The replane crate brings feature flags, operational settings, and per-user overrides to Rust services, with values that update in realtime and reads that never leave the process.
Installation
cargo add replane
cargo add tokio --features macros,rt-multi-thread
The SDK is async and runs on Tokio. TLS uses rustls by default; enable the native-tls feature to use the platform's TLS instead.
Quick start
use replane::{ConnectOptions, Context, Replane};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let replane = Replane::builder()
.default_value("api-rate-limit", 100)
.default_value("feature-new-checkout", false)
.connect(ConnectOptions::new(
"https://replane.example.com",
std::env::var("REPLANE_SDK_KEY")?,
))
.await?;
// Read a value
let limit: u32 = replane.get("api-rate-limit")?;
// Read with context for override evaluation
let context = Context::new().with("userId", "user-123").with("plan", "premium");
let user_limit: u32 = replane.get_with("api-rate-limit", &context)?;
println!("limit: {limit}, premium limit: {user_limit}");
Ok(())
}
connect waits for the initial set of configs, so values are ready as soon as it returns. After that, the SDK keeps a Server-Sent Events stream open and applies changes as they're published, reconnecting automatically if the connection drops.
Typed configs with serde
Config values are JSON, and get deserializes them into any type that implements Deserialize:
use serde::Deserialize;
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct Pricing {
free_requests: u32,
premium_requests: u32,
}
let pricing: Pricing = replane.get("pricing")?;
If a config is missing or has an unexpected shape, get returns an error you can match on. On hot paths, get_or returns a fallback instead.
Overrides are evaluated locally
Override rules, like "premium users get a higher limit" or "enable for 10% of users", are evaluated inside the SDK against the context you pass. No request is made per read, so checking a flag in a request handler costs a map lookup and a few comparisons.
For per-request code, with_context creates a client that carries the context with it. It shares configs and the connection with the original, so it's cheap to create per request:
let user_client = replane.with_context(&Context::new().with("userId", "user-123"));
let enabled = user_client.get_or("feature-new-checkout", false);
Reacting to changes
Most code just reads the current value when it needs it. For long-lived state, like a connection pool or a rate limiter, subscribe to changes:
let subscription = replane.subscribe("api-rate-limit", |change| {
println!("{} changed to {}", change.name, change.value);
});
The subscription stops when it's dropped; call .detach() to keep it for the lifetime of the client.
Testing without a server
A client built without connecting works entirely in memory, so tests don't need a Replane instance:
#[test]
fn uses_new_checkout() {
let replane = Replane::builder()
.default_value("feature-new-checkout", true)
.build();
assert!(replane.get::<bool>("feature-new-checkout").unwrap());
}
To test override rules, seed the client with a snapshot of configs. The guide has an example.
Fits into your service
Replane is cheap to clone and safe to share across threads, so it can sit directly in your axum or actix state. The SDK logs connection events through tracing, and you can pass your own reqwest::Client for proxies or custom certificates.
Get started
- Rust SDK docs: /docs/sdk/rust
- crates.io: crates.io/crates/replane
- API docs: docs.rs/replane
- GitHub: github.com/replane-dev/replane-rust
The SDK is MIT licensed. Issues and pull requests are welcome.
Try Replane
Replane is an open-source dynamic configuration platform with real-time updates via SSE, version history, instant rollback, and SDKs for JavaScript, Python, .NET, and Rust.
- Quickstart — Deploy Replane locally in minutes
- Self-hosting guide — Run on your own infrastructure
- Documentation — Full reference and guides
MIT licensed. View on GitHub.
