Built with AI. Murmer is built and maintained with the help of AI coding tools, primarily Claude. I drive the design and review every change, but a lot of the implementation, tests, and docs are written in collaboration with AI.
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.3"
= { = "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.
Other libraries to consider
Murmer is still v0 and an experiment. For anything real, you should probably consider using one of these instead. They inspired Murmer and most of them are far more mature:
- Erlang/Elixir OTP — the actor model and supervision tree that started it all for me. If you can run on the BEAM, OTP is decades of battle-tested production experience.
- Apple Swift Distributed Actors — the typed, location-transparent endpoint design that shaped Murmer's API. Worth reading even if you're not writing Swift.
- Actix — the most established actor framework in Rust. Mature, fast, and great for in-process actors.
- ractor — a newer Rust actor library inspired by Erlang, with a clustering story of its own. Well worth a look if you're comparing options.
License
Licensed under either of
at your option.