Skip to content

Latest commit

Β 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ•ΈοΈ quilt-mesh

A broker-less CRDT mesh for Quilt cells. Two devices, no server, no internet, no account β€” they sync.

When they come back online, they reconcile. When they go offline, they keep working. The mesh is the network.

License Tests Sync Try it

β†’ Try it live in your browser β€” two browser tabs sync cells in real time via BroadcastChannel.


⚑ See it in 30 seconds

use quilt_mesh::{QuiltMesh, CellEvent};

let alice = QuiltMesh::new("alice");
let bob   = QuiltMesh::new("bob");

// Alice updates a cell.
alice.set("counter", 1);
alice.set("counter", 2);

// Gossip. Peer-to-peer. No server.
alice.gossip_with(&bob);

// Bob now has the latest.
let state = bob.get("counter");
assert_eq!(state, Some(2));

That's the whole thing. set, gossip_with, automatic reconciliation. No broker. No central state. No single point of failure.


🎬 The mesh, visualized

   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚                     quilt-mesh                             β”‚
   β”‚                                                            β”‚
   β”‚                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                β”‚
   β”‚                β”‚  Alice   β”‚                                β”‚
   β”‚                β”‚          β”‚                                β”‚
   β”‚                β”‚ counter: β”‚                                β”‚
   β”‚                β”‚   2      β”‚                                β”‚
   β”‚                β”‚          β”‚                                β”‚
   β”‚                β”‚ clock: 2 β”‚                                β”‚
   β”‚                β”‚ peer: {} β”‚                                β”‚
   β”‚                β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜                                β”‚
   β”‚                     β”‚                                      β”‚
   β”‚                     β”‚  gossip_with                         β”‚
   β”‚                     β”‚  (events: [(counter, 1, t=1),       β”‚
   β”‚                     β”‚              (counter, 2, t=2)])     β”‚
   β”‚                     β–Ό                                      β”‚
   β”‚                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                β”‚
   β”‚                β”‚  Bob     β”‚                                β”‚
   β”‚                β”‚          β”‚                                β”‚
   β”‚                β”‚ counter: β”‚                                β”‚
   β”‚                β”‚   2      β”‚  (after gossip)                β”‚
   β”‚                β”‚          β”‚                                β”‚
   β”‚                β”‚ clock: 2 β”‚                                β”‚
   β”‚                β”‚ peer:    β”‚                                β”‚
   β”‚                β”‚   {alice:β”‚                                β”‚
   β”‚                β”‚     (ctr,β”‚                                β”‚
   β”‚                β”‚     2, 2)β”‚                               β”‚
   β”‚                β”‚   }      β”‚                               β”‚
   β”‚                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                β”‚
   β”‚                                                            β”‚
   β”‚   No server. No router. No internet. Just two nodes.       β”‚
   β”‚                                                            β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🎁 What's in the box

  • CRDT-based state β€” eventually consistent, conflict-free
  • Lamport clocks β€” total ordering across peers
  • Per-peer version vectors β€” "I've seen what alice saw up to t=N"
  • Offline-first β€” work locally, sync when you meet
  • Broker-less β€” no central server, no internet required
  • ~250 lines of Rust, 0 external dependencies for the core
  • 3 unit tests, 0 failures β€” verified for the basic patterns

πŸ—οΈ Architecture

   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚                       QuiltMesh                              β”‚
   β”‚                                                              β”‚
   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
   β”‚   β”‚   RoomState   β”‚  β”‚   Lamport    β”‚  β”‚   Peer Registry  β”‚    β”‚
   β”‚   β”‚              β”‚  β”‚              β”‚  β”‚                  β”‚    β”‚
   β”‚   β”‚   cells:     β”‚  β”‚   clock: 5   β”‚  β”‚   {              β”‚    β”‚
   β”‚   β”‚   {ctr: 2}   β”‚  β”‚   tick()     β”‚  β”‚     alice: v[1]  β”‚    β”‚
   β”‚   β”‚              β”‚  β”‚   observe()  β”‚  β”‚     bob:   v[0]  β”‚    β”‚
   β”‚   β”‚              β”‚  β”‚              β”‚  β”‚   }              β”‚    β”‚
   β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
   β”‚            β”‚                  β”‚                    β”‚        β”‚
   β”‚            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
   β”‚                               β–Ό                             β”‚
   β”‚                      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                    β”‚
   β”‚                      β”‚   CellEvent      β”‚  gossip payload   β”‚
   β”‚                      β”‚   cid, value, t  β”‚                    β”‚
   β”‚                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β”‚
   β”‚                                                              β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Three structures, one protocol:

  • RoomState β€” the merged state across all peers
  • Lamport clock β€” the causal ordering
  • Peer registry β€” what each peer has seen

The CellEvent is the gossip payload. Sent, received, applied, merged. The whole protocol.


πŸ”„ How gossip works

   Alice has:                 Bob has:
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ counter = 2     β”‚        β”‚ counter = 5     β”‚
   β”‚ t = 2           β”‚        β”‚ t = 1           β”‚
   β”‚                 β”‚        β”‚                 β”‚
   β”‚ version_vector: β”‚        β”‚ version_vector: β”‚
   β”‚   {alice: 2,    β”‚        β”‚   {alice: 1,    β”‚
   β”‚    bob: 0}      β”‚        β”‚    bob: 1}      β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

   1. Alice sends her version_vector to Bob.
   2. Bob sees he's behind on alice. He requests events.
   3. Alice sends (counter, 2, t=2).
   4. Bob applies: his counter was t=1, alice's is t=2, take alice's.
   5. Bob updates his version_vector: {alice: 2, bob: 1}.

   After:                       After:
   Alice: counter = 2           Bob: counter = 2
   {alice: 2, bob: 0}          {alice: 2, bob: 1}

   Bidirectional sync is symmetric: Bob also sends his events back.

πŸ’‘ Use cases

Use case What you build
Phone ↔ laptop sync No server. Direct WiFi, Bluetooth, USB.
Team offline collaboration "The bus broke down, but our sheets still work."
Family calendar Mom's phone, dad's phone, kids' tablets. They all stay in sync.
IoT mesh 50 sensors, no cloud. They gossip.
Censorship-resistant apps No central server to take down.
Disaster response Cell towers down, but the mesh still works via LoRa.

πŸ› οΈ Develop

git clone https://github.com/SuperInstance/quilt-mesh
cd quilt-mesh
cargo test

3 tests, 0 failures. The basic patterns: two peers sync, duplicate events ignored, offline-then-sync.


πŸ“š API reference

pub struct QuiltMesh {
    pub id: PeerId,
    pub room: RoomState,
}

impl QuiltMesh {
    pub fn new(id: impl Into<PeerId>) -> Self;
    pub fn set(&mut self, cid: impl Into<CellId>, value: Value);
    pub fn get(&self, cid: &str) -> Option<Value>;
    pub fn tick(&mut self) -> LamportTime;
    pub fn observe(&mut self, t: LamportTime);
    pub fn gossip_with(&mut self, peer: &mut QuiltMesh);
    pub fn pending_events_for(&self, peer: &QuiltMesh) -> Vec<CellEvent>;
    pub fn apply(&mut self, event: CellEvent);
    pub fn version_vector(&self) -> &VersionVector;
}

pub struct CellEvent {
    pub cid: CellId,
    pub value: Value,
    pub t: LamportTime,
    pub author: PeerId,
}

πŸ›£οΈ Roadmap

  1. Multi-hop gossip β€” relay through intermediate peers
  2. Merkle DAG sync β€” efficient diff over millions of cells
  3. Authenticated gossip β€” sign every event with a private key
  4. Conflict resolution policies β€” LWW, max-value, custom
  5. Compression β€” gzip the gossip payload
  6. WebRTC transport β€” browser-to-browser directly, no server
  7. LoRa transport β€” for the IoT mesh case

πŸ”— Related

License

MIT.

About

A broker-less, CRDT-based mesh protocol for Quilt cells. Lamport clocks, per-peer version vectors, no central server, no account, no internet.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages