| Crates.io | sprites |
| lib.rs | sprites |
| version | 0.1.0 |
| created_at | 2026-01-13 00:55:04.13162+00 |
| updated_at | 2026-01-13 00:55:04.13162+00 |
| description | Official Rust SDK for Sprites - stateful sandbox environments from Fly.io |
| homepage | https://sprites.dev |
| repository | https://github.com/m-mohamed/sprites-rs |
| max_upload_size | |
| id | 2039115 |
| size | 206,342 |
Official Unofficial Rust SDK for Sprites - stateful sandbox environments from Fly.io.
Sprites are lightweight, persistent VMs powered by Firecracker. They hibernate when idle (no compute cost) and wake instantly when needed. Create checkpoints in ~300ms and restore to any previous state.
Add to your Cargo.toml:
[dependencies]
sprites = "0.1"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
use sprites::SpritesClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a client with your API token
let client = SpritesClient::new(std::env::var("SPRITES_TOKEN")?);
// Create a sprite
let sprite = client.create("my-sprite").await?;
// Run commands
let output = sprite.command("uname").arg("-a").output().await?;
println!("{}", output.stdout_str());
// Create a checkpoint
let checkpoint = sprite.checkpoint("Initial state").await?;
println!("Created checkpoint: {}", checkpoint.id);
// Clean up
sprite.destroy().await?;
Ok(())
}
The Command API mirrors std::process::Command:
let output = sprite
.command("npm")
.arg("install")
.current_dir("/app")
.env("NODE_ENV", "production")
.output()
.await?;
if output.success() {
println!("stdout: {}", output.stdout_str());
} else {
eprintln!("stderr: {}", output.stderr_str());
}
For long-running processes, use spawn() for streaming I/O:
let mut child = sprite.command("npm").arg("run").arg("dev").spawn().await?;
// Wait for completion
let status = child.wait().await?;
println!("Process exited with: {:?}", status);
Create snapshots for instant rollback (~300ms):
// Checkpoint before risky operations
let checkpoint = sprite.checkpoint("Before migration").await?;
// Run migrations...
sprite.command("npm").arg("run").arg("migrate").output().await?;
// If something goes wrong, restore instantly
sprite.restore(&checkpoint.id).await?;
// List all checkpoints
let checkpoints = sprite.list_checkpoints().await?;
for cp in checkpoints {
println!("{}: {:?}", cp.id, cp.comment);
}
Control egress with DNS-based filtering:
use sprites::{NetworkPolicy, NetworkPolicyRule, PolicyAction};
let policy = NetworkPolicy {
rules: vec![
NetworkPolicyRule {
domain: "api.anthropic.com".into(),
action: PolicyAction::Allow,
},
NetworkPolicyRule {
domain: "*.npmjs.org".into(),
action: PolicyAction::Allow,
},
NetworkPolicyRule {
domain: "*".into(),
action: PolicyAction::Deny,
},
],
include: vec![], // Optional policy bundles
};
sprite.set_policy(policy).await?;
Read and write files without executing commands:
let fs = sprite.filesystem();
// Read a file
let content = fs.read_file("/app/config.json").await?;
// Write a file
fs.write_file("/app/data.txt", b"Hello, Sprites!").await?;
// List directory
let entries = fs.read_dir("/app").await?;
for entry in entries {
println!("{}: {} bytes", entry.name, entry.size);
}
Proxy local ports to your sprite:
// Forward local:8080 -> sprite:3000
let proxy = sprite.proxy_port(8080, 3000).await?;
println!("Proxy listening on {}", proxy.local_addr());
// Access your sprite's server at localhost:8080
// ...
proxy.close().await?;
Get your API token from sprites.dev or exchange Fly.io credentials:
// Using Fly.io macaroon
let token = SpritesClient::create_token(
std::env::var("FLY_API_TOKEN")?,
"your-org-slug",
None,
).await?;
let client = SpritesClient::new(token);
Use the builder for advanced configuration:
use std::time::Duration;
let client = SpritesClient::builder(token)
.base_url("https://api.sprites.dev")
.timeout(Duration::from_secs(30))
.build();
See the examples directory:
# Basic usage
cargo run --example basic
# Debug exec streaming
cargo run --example exec_debug
See CONTRIBUTING.md for development setup and guidelines.
Apache-2.0 - see LICENSE for details.