Skip to content

Architecture Overview

Calimero’s architecture consists of four main layers that work together to enable distributed, peer-to-peer applications with automatic conflict-free synchronization.

flowchart LR
    APP[Application<br/>WASM apps & SDK] --> NODE[Node<br/>Sync & execution]
    NODE --> STORAGE[Storage<br/>CRDT & DAG]
    STORAGE --> NETWORK[Network<br/>P2P & APIs]
    NETWORK -.-> NODE
    
    style APP fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style NODE fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style STORAGE fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style NETWORK fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff

Transaction Flow:

flowchart LR
    CLIENT[Client<br/>RPC call] --> NODE[Node<br/>Execute]
    NODE --> WASM[WASM<br/>Process]
    WASM --> STORAGE[Storage<br/>CRDT ops]
    STORAGE --> NODE
    NODE --> NETWORK[Network<br/>Broadcast]
    NETWORK --> PEER[Peer<br/>~100ms]
    NODE --> CLIENT
    
    style CLIENT fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style NODE fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style WASM fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style STORAGE fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style NETWORK fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style PEER fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff

See core/crates/runtime/README.md for execution details.

Calimero uses a dual-path synchronization strategy:

Fast real-time propagation (~100-200ms):

flowchart LR
    TXN[Execute] --> DELTA[Create Delta]
    DELTA --> GOSSIP[Gossipsub]
    GOSSIP --> RECEIVE[Peers receive]
    RECEIVE --> READY{Ready?}
    READY -->|Yes| APPLY[Apply]
    READY -->|No| BUFFER[Buffer]
    APPLY --> EVENTS[Events]
    
    style TXN fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style DELTA fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style GOSSIP fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style RECEIVE fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style READY fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style APPLY fill:#000000,stroke:#00ff00,stroke-width:4px,color:#ffffff
    style EVENTS fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style BUFFER fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff

Catch-up every 10-30 seconds:

flowchart LR
    TIMER[Timer] --> PEER[Select Peer]
    PEER --> STREAM[Open Stream]
    STREAM --> HEADS[Exchange Heads]
    HEADS --> DIFF{Differ?}
    DIFF -->|Yes| REQUEST[Request Deltas]
    DIFF -->|No| SYNC[Synced]
    REQUEST --> APPLY2[Apply]
    APPLY2 --> SYNC
    
    style TIMER fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style PEER fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style STREAM fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style HEADS fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style DIFF fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style REQUEST fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style APPLY2 fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style SYNC fill:#000000,stroke:#00ff00,stroke-width:4px,color:#ffffff

Why both paths?

  • Gossipsub: Fast (~100-200ms), reliable in good network conditions
  • Periodic sync: Ensures eventual consistency even with packet loss, partitions, or downtime

See core/crates/node/README.md for sync configuration details.

The DAG ensures deltas are applied in correct causal order:

flowchart LR
    ROOT[Root] --> A[Delta A]
    ROOT --> B[Delta B]
    A --> MERGE[Merge]
    B --> MERGE
    
    style ROOT fill:#000000,stroke:#00ff00,stroke-width:4px,color:#ffffff
    style A fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style B fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style MERGE fill:#000000,stroke:#00ff00,stroke-width:4px,color:#ffffff

Key properties:

  • Deltas can arrive in any order
  • System buffers deltas until their parent dependencies are ready
  • Once parents are available, deltas are applied automatically in causal order
  • Concurrent updates create forks that merge automatically
flowchart LR
    SERVER[Server] --> NODE[Node]
    NODE --> RUNTIME[Runtime]
    NODE --> NETWORK[Network]
    SDK[SDK] --> RUNTIME
    RUNTIME --> STORAGE[Storage]
    STORAGE --> DAG[DAG]
    
    style SDK fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style RUNTIME fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style STORAGE fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style DAG fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style NODE fill:#000000,stroke:#00ff00,stroke-width:4px,color:#ffffff
    style NETWORK fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    style SERVER fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
ComponentPurposeRepository
SDK#[app::state], #[app::logic], CRDT collections, eventscore/crates/sdk
RuntimeWASM execution (Wasmer), sandboxingcore/crates/runtime
StorageCRDT collections, merge semanticscore/crates/storage
DAGCausal delta tracking, dependency resolutioncore/crates/dag
NodeNodeManager orchestrates sync, events, blobscore/crates/node
Networklibp2p P2P (Gossipsub, streams, DHT)core/crates/network
ServerJSON-RPC API, WebSocket/SSEcore/crates/server
merodNode binary (coordinator/peer)core/crates/merod
meroctlCLI for node operationscore/crates/meroctl

See core/README.md for complete architecture.

For detailed information on each component, see their README files:

For detailed architecture information:


Next: Learn about specific concepts: Contexts | Identity | Applications | Nodes