A fault-tolerant actor runtime for Rust. Like React, but for concurrent systems.
Sprite is a Rust library for building fault-tolerant, concurrent actor systems with a clean, declarative API inspired by React.
Instead of writing complex supervision trees and manual error handling, you write actor components — pure setup closures that declare state, message handlers, and children. If an actor panics, Sprite automatically resurrects it in under 50 nanoseconds with its state intact.
use sprite_core::{Engine, Message};
fn main() {
let engine = Engine::new();
let counter = engine.spawn("counter", |ctx| {
// Like React's useState — survives crashes
let count = ctx.use_state("count", 0i64);
ctx.on_message(move |msg| {
if msg == "inc" {
count.update(|c| c + 1);
println!("count = {}", count.get());
}
});
});
counter.send(Message::text("inc"));
counter.send(Message::text("inc"));
}| Concept | React Equivalent | What it does |
|---|---|---|
Engine |
createRoot |
The runtime that mounts and manages actors |
engine.spawn(name, |ctx| { ... }) |
<Component /> |
Creates an actor from a setup closure |
ctx.use_state(key, initial) |
useState |
Declares typed state that survives crashes |
ctx.use_scratch(initial) |
useRef |
Ephemeral value wiped on recovery |
ctx.on_message(|msg| { ... }) |
onClick / event handler |
Registers a message handler |
ctx.on_panic(| | { ... }) |
componentDidCatch |
Runs after each panic recovery |
ctx.on_mount(| | { ... }) |
useEffect([], ...) |
Runs once on first start |
ctx.on_unmount(| | { ... }) |
cleanup function | Runs on graceful shutdown |
ctx.spawn(name, ...) |
child components | Spawns nested actors |
ctx.send_to(id, msg) |
props callback | Sends a message to another actor |
ctx.send_named(name, msg) |
— | Sends to a named actor |
ctx.poll() |
— | Non-blocking message check |
ctx.sleep(dur) |
— | Yield without blocking thread |
Handle::send(msg) |
setState / props |
Sends a message to an actor |
Handle::send_msg(any) |
— | Send any IntoMessage type |
Handle::request(msg, timeout) |
fetch |
Request/response pattern |
[ Panic in Actor ]
│
▼
catch_unwind catches it (~0.05ms)
│
▼
Arena reset (~1ns)
│
▼
State already intact (0ns — lives in shared store)
│
▼
Setup closure re-runs (~1ms)
│
▼
Actor Fully Restored (< 50ns for recovery core)
State created via use_state lives in a shared store outside the actor thread, so it survives panics automatically. The actor's scratch allocations (via bumpalo) are reset, but your data is safe.
If an actor panics more than 10 times in 5 seconds, Sprite trips a circuit breaker and halts it — preventing infinite crash loops.
engine.spawn("fragile", |ctx| {
ctx.on_message(|_| panic!("always"));
// After 10 recoveries, this actor stops.
});[dependencies]
sprite-core = { git = "https://github.com/dragprog/sprite-engine" }use sprite_core::{Engine, Message, Pool};
let engine = Engine::new();
let pool = Pool::new(&engine, "worker", 4, |ctx| {
ctx.on_message(|task| {
println!("Worker {} processing: {:?}", ctx.id(), task);
});
});
for i in 0..100 {
pool.send(Message::int(i));
}engine.broadcast(Message::text("shutdown"));engine.spawn("logger", |ctx| {
ctx.on_message(|msg| println!("{:?}", msg));
});
engine.send_named("logger", Message::text("hello"));
assert_eq!(engine.lookup("logger"), Some(id));use sprite_core::Timer;
use std::time::Duration;
Timer::send_after(handle.tx.clone(), Duration::from_secs(5), Message::text("timeout"));use sprite_core::{Engine, ActorBuilder};
let handle = ActorBuilder::new("worker", |ctx| {
ctx.on_message(|msg| { /* ... */ });
})
.arena_size(1024 * 128)
.max_recoveries(5)
.recovery_window(Duration::from_secs(10))
.spawn(&engine);git clone https://github.com/dragprog/sprite-engine.git
cd sprite-engine
cargo test --workspace
cargo bench --bench recovery_speed
cargo bench --bench mailbox_throughput
cargo run --example counter
cargo run --example pool
cargo run --example broadcast| Benchmark | Target |
|---|---|
recovery_speed |
Panic → full restore |
mailbox_throughput |
Messages / second |
- Fork the repo (
git checkout -b feature/cool-thing). - Keep the API surface minimal and ergonomic.
- Ensure tests pass (
cargo test). - Submit a PR with a concise breakdown.
Distributed under the Apache License 2.0. See LICENSE for details.