6 releases
| 0.1.1 | Jan 29, 2026 |
|---|---|
| 0.1.0 | Jan 13, 2026 |
| 0.0.5 |
|
| 0.0.4 | Dec 18, 2025 |
| 0.0.3 | Nov 25, 2025 |
#386 in Web programming
11,085 downloads per month
135KB
3K
SLoC
GrowthBook Rust SDK
[!NOTE] This repo was originally developed by the community and later adopted by GrowthBook.
The official GrowthBook SDK for Rust. This crate provides an easy way to integrate feature flagging and experimentation into your Rust applications.
Installation
[dependencies] growthbook-rust = "0.1.1"
Use the GrowthBookClientBuilder to create a client instance. This supports auto-refreshing features, caching, and callbacks.
use growthbook_rust::client::GrowthBookClientBuilder;
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = GrowthBookClientBuilder::new()
.api_url("https://cdn.growthbook.io".to_string())
.client_key("sdk-key".to_string())
.ttl(Duration::from_secs(60)) // Cache TTL
.auto_refresh(true) // Enable background updates
.refresh_interval(Duration::from_secs(30))
.build()
.await?;
Ok(())
}
Checking Features
You can check if a feature is enabled or get its value.
// Simple check
if client.is_on("my-feature", None) {
println!("Feature is enabled!");
}
// Get typed value
let value = client.feature_result("my-config", None).value_as::<String>()?;
Context & Attributes
You can set global attributes that apply to all evaluations, and override them per-check.
use std::collections::HashMap;
use growthbook_rust::model_public::{GrowthBookAttribute, GrowthBookAttributeValue};
// Global attributes
let mut global_attrs = HashMap::new();
global_attrs.insert("tenantId".to_string(), GrowthBookAttributeValue::String("123".to_string()));
let client = GrowthBookClientBuilder::new()
.api_url(api_url)
.client_key(sdk_key)
.attributes(global_attrs)
.build()
.await?;
// Per-check attributes (merged with global)
let mut user_attrs = Vec::new();
user_attrs.push(GrowthBookAttribute::new("userId".to_string(), GrowthBookAttributeValue::String("456".to_string())));
if client.is_on("my-feature", Some(user_attrs)) {
// ...
}
Tracking Callbacks
You can subscribe to events for tracking and analytics.
let client = GrowthBookClientBuilder::new()
// ...
.on_feature_usage(Box::new(|key, result| {
println!("Feature '{}' evaluated: {:?}", key, result.value);
}))
.on_experiment_viewed(Box::new(|experiment_result| {
// Track experiment impression
println!("Experiment viewed: {}", experiment_result.key);
}))
.build()
.await?;
Configuration
The SDK can also be configured via environment variables if not explicitly set in the builder:
| Env Var | Description |
|---|---|
| GB_HTTP_CLIENT_TIMEOUT | Timeout for HTTP requests. Default: 10s |
| GB_UPDATE_INTERVAL | Interval for auto-refresh (if enabled). Default: 60s |
| GB_URL | GrowthBook API URL |
| GB_SDK_KEY | GrowthBook SDK Key |
Refreshing features & Caching
The SDK supports automated feature updates via a background task. This is enabled by default when using auto_refresh(true) in the builder.
- Caching: Features are cached in memory by default. You can configure the TTL using
.ttl(Duration::from_secs(60)). - Background Sync: When
auto_refreshis enabled, a background task periodically fetches features from the API and updates the cache. - On Refresh Callback: You can listen for updates using
.add_on_refresh(...).
Manual Feature Management
If you prefer to manage feature updates manually or want to start with a specific set of features (e.g., from a file or another source), you can disable auto-refresh and provide initial features.
use serde_json::json;
let features_json = json!({
"my-feature": {
"defaultValue": true
}
});
let client = GrowthBookClientBuilder::new()
.api_url(api_url)
.client_key(sdk_key)
.auto_refresh(false) // Disable background sync
.features_json(features_json)? // Set features manually
.build()
.await?;
// You can manually refresh features later
client.refresh().await;
Encrypted Features
If you are using encrypted features, you can provide the decryption key to the builder.
let client = GrowthBookClientBuilder::new()
.api_url(api_url)
.client_key(sdk_key)
.decryption_key("your-decryption-key".to_string())
.build()
.await?;
Sticky Bucketing
The SDK supports Sticky Bucketing to ensure users persist in their assigned variations, even if the user session changes or targeting conditions update.
Using the Default In-Memory Service
For simple applications where persistence across restarts is not required (or for testing), you can use the built-in InMemoryStickyBucketService.
use std::sync::Arc;
use growthbook_rust::sticky_bucket::InMemoryStickyBucketService;
let sticky_service = Arc::new(InMemoryStickyBucketService::new());
let client = GrowthBookClientBuilder::new()
.api_url(api_url)
.client_key(sdk_key)
.sticky_bucket_service(sticky_service)
.build()
.await?;
Custom Sticky Bucket Implementation
For production use cases requiring durable storage (Redis, Database, LocalStorage, etc.), you should implement the StickyBucketService trait.
use std::collections::HashMap;
use growthbook_rust::sticky_bucket::StickyBucketService;
use growthbook_rust::model_public::GrowthBookAttribute;
#[derive(Debug)]
pub struct MyRedisStickyBucketService {
// ... connection pool etc.
}
impl StickyBucketService for MyRedisStickyBucketService {
fn get_assignments(&self, attribute_name: &str, attribute_value: &str) -> Option<HashMap<String, String>> {
// Fetch from Redis usually returning Key (experiment_key) -> Value (variation_key)
// ...
None
}
fn save_assignments(&self, attribute_name: &str, attribute_value: &str, assignments: HashMap<String, String>) {
// Write to Redis
// ...
}
fn get_all_assignments(&self, attributes: &HashMap<String, GrowthBookAttribute>) -> HashMap<String, String> {
// Batch fetch all assignments for the given user attributes
HashMap::new()
}
}
Dependencies
~16–27MB
~385K SLoC