Typed, location-transparent actors that communicate through message passing. Whether an actor lives in the same process or on a remote node across the network, you interact with it through the same Endpoint<A> API.
┌─ local ──→ Actor (in-memory, zero-copy)
Your Code → Endpoint<A> ──┤
└─ remote ─→ QUIC stream (bincode, encrypted) ──→ Actor (remote node)
Highlights
| Location-transparent | Same Endpoint<A> API whether the actor is local or on another node |
| Minimal boilerplate | #[handlers] generates message structs, dispatch tables, and extension traits from plain method signatures |
| Networking included | QUIC transport, TLS encryption, SWIM membership, mDNS discovery — configured, not hand-rolled |
| OTP-style supervision | Restart policies (Temporary, Transient, Permanent) with limits and exponential backoff |
| Edge clients | Lightweight MurmerClient connects to a cluster and calls public actors without joining it |
| Test without infra | Spin up multi-node clusters in-memory from a single process |
Quick Start
[]
= "0.1"
= { = "1", = ["derive"] }
= { = "1", = ["full"] }
Define an actor:
use *;
;
Use it:
async
Go distributed — swap one line, your actor code stays the same:
// Before: let system = System::local();
let system = clustered.await?;
// Everything else is identical
let counter = system.start;
let remote = system..unwrap;
remote.get_count.await?; // transparently serialized over QUIC
Edge Clients
Not everything that talks to your cluster needs to join it. Use MurmerClient to connect from a REST gateway, CLI tool, or test runner and call public actors directly:
use MurmerClient;
let client = connect.await?;
let ep = client..unwrap;
let user = ep.send.await?;
client.disconnect.await;
Mark actors as public on the server side with system.start_public():
// Visible to Edge clients
let api = system.start_public;
// Internal cluster actors — not visible to Edge clients (default)
let router = system.start;
lookup_wait blocks until the actor appears — useful when connecting before the cluster has finished placing actors:
let ep = client
.
.await?;
See the Edge Clients chapter in the book for the full API, visibility model, and scalability details.
Documentation
| Resource | Description |
|---|---|
| The Murmer Book | User guide: actors, discovery, supervision, clustering, macros, orchestration |
| API Reference | Rustdoc on docs.rs |
| Examples | Runnable demos: counter, cluster chat, orchestrator, edge client |
Build & Test
Why murmer?
I've spent years working with Elixir and the BEAM VM, and the actor model there is something I've grown deeply fond of — the simplicity of processes, message passing, and supervision just works. When I looked at bringing that experience to Rust, the existing frameworks were impressive but getting a basic actor up and running was complex, and adding remote communication was even more so.
Murmer is an experiment in answering: can you build a robust distributed actor system in Rust that's actually simple to use? The design draws from BEAM OTP, Akka's clustering, and Apple's Swift Distributed Actors — combined with Rust's performance and safety guarantees.
License
Licensed under either of
at your option.