License Erlang/OTP Hex.pm Buy Me A Coffee

Macula

BEAM-native HTTP/3 mesh networking for decentralized applications


What is Macula?

Macula is an Erlang/OTP library that provides a complete distributed mesh networking stack over HTTP/3 (QUIC). It enables BEAM applications to form self-organizing networks with:

  • Zero configuration clustering via UDP multicast gossip
  • NAT-friendly transport using QUIC (single UDP port)
  • Decentralized service discovery via Kademlia DHT
  • Capability-based security with DID identities and UCAN tokens

Macula Mesh Architecture


Features

Mesh Networking

Macula Overview

FeatureDescription
HTTP/3 over QUICNAT-friendly, firewall-friendly, built-in TLS 1.3
Kademlia DHTDecentralized routing with O(log N) lookups
Multi-tenant realmsIsolated namespaces for different applications
Connection pooling94.5% hit rate, LRU eviction

Pub/Sub Messaging

PubSub Flow

%% Subscribe to a topic
ok = macula:subscribe(Peer, <<"sensors.temperature">>, fun(Msg) ->
    io:format("Received: ~p~n", [Msg])
end).

%% Publish to subscribers
ok = macula:publish(Peer, <<"sensors.temperature">>, #{value => 23.5}).

RPC (Request/Response)

RPC Flow

%% Register a procedure handler
ok = macula:register(Peer, <<"math.add">>, fun(#{a := A, b := B}) ->
    {ok, #{result => A + B}}
end).

%% Call the procedure (discovers provider via DHT)
{ok, #{result := 5}} = macula:call(Peer, <<"math.add">>, #{a => 2, b => 3}).

NAT Traversal

NAT Traversal

TechniqueStatusDescription
Hole PunchingAdaptiveDirect P2P through NAT
STUN-like ProbingBuilt-inReflexive address detection
Relay FallbackAutomaticWhen direct fails
Connection UpgradeTransparentRelay → Direct when possible

Gossip Clustering

Gossip Clustering

Zero-configuration cluster formation using UDP multicast:

%% Start gossip-based clustering
ok = macula_cluster:start_cluster(#{
    strategy => gossip,
    secret => <<"my_cluster_secret">>  %% Optional HMAC authentication
}).

%% Nodes auto-discover via multicast 230.1.1.251:45892

Content Transfer (P2P Artifacts)

Content Transfer

Content-addressed storage and transfer for distributing OTP releases across the mesh:

%% Publish a file to the mesh
{ok, MCID} = macula_content:publish("/path/to/release.tar.gz").

%% Fetch from any provider
{ok, Binary} = macula_content:fetch(MCID).
FeatureDescription
MCIDContent-addressed identifiers (BLAKE3/SHA256)
Merkle verificationChunk-level integrity
Parallel downloadFrom multiple providers
Want/Have/BlockEfficient P2P protocol

Authorization (DID + UCAN)

Authorization Flow

Decentralized capability-based authorization:

ComponentPurpose
DIDDecentralized identifiers for namespace ownership
UCANCapability tokens for delegated permissions
Namespacedid:macula:io.example.user owns io.example.user.*

Hierarchical DHT (Bridge System)

Kademlia DHT

Fractal mesh hierarchy with query escalation:

Cluster  Street  Neighborhood  City  Province  Country  Region  Global

When a DHT query fails locally, it escalates to parent levels with results cached at lower levels.


Quick Start

Installation

Add to your rebar.config:

{deps, [
    {macula, "0.19.2"}
]}.

Or in Elixir mix.exs:

defp deps do
  [
    {:macula, "~> 0.19.2"}
  ]
end

Basic Usage

%% Start macula application
application:ensure_all_started(macula).

%% Connect to the mesh
{ok, Peer} = macula:connect(<<"quic://seed.example.com:9443">>, #{
    realm => <<"io.example.myapp">>,
    node_id => <<"node-001">>
}).

%% Subscribe to events
macula:subscribe(Peer, <<"events.orders">>, fun(Order) ->
    process_order(Order)
end).

%% Make RPC calls
{ok, Result} = macula:call(Peer, <<"inventory.check">>, #{sku => <<"ABC123">>}).

Configuration

Environment Variables

VariableDefaultDescription
MACULA_QUIC_PORT9443QUIC listener port
MACULA_REALMcom.example.realmDefault realm
HEALTH_PORT8080Health check HTTP port
MACULA_TLS_MODEdevelopmentTLS mode (production/development)
CLUSTER_STRATEGYgossipCluster strategy (gossip/static/mdns)
CLUSTER_SECRET-Shared secret for gossip HMAC

Application Config

{macula, [
    {quic_port, 9443},
    {realm, <<"io.example.myapp">>},
    {tls_mode, production},
    {tls_cacertfile, "/etc/ssl/certs/ca-certificates.crt"}
]}.

Documentation

GuideDescription
Cluster API GuideClustering and distribution
Gossip Clustering GuideUDP multicast discovery
Content Transfer GuideP2P artifact distribution
NAT Traversal GuideNAT techniques
DHT GuideKademlia DHT internals
Authorization GuideDID/UCAN security
TLS ConfigurationProduction TLS setup

Version History

VersionDateHighlights
v0.19.2Jan 2026README rework with feature sections and SVGs
v0.19.1Jan 2026Gossip clustering, static strategy (34 tests)
v0.19.0Jan 2026Content transfer system, MCID, Want/Have/Block (171 tests)
v0.18.0Jan 2026Cluster API for bc_gitops integration (19 tests)
v0.16.0Dec 2025Registry system, Ed25519 signing (60 tests)
v0.15.0Dec 2025Gossip protocol, CRDT replication (29 tests)
v0.14.0Dec 2025Masterless CRDT architecture (48 tests)
v0.13.0Dec 2025Hierarchical DHT, bridge system (40 tests)
v0.12.0Nov 2025Complete NAT traversal (70 tests)

See CHANGELOG.md for full history.


Architecture

Macula follows an always-on architecture where every node has all capabilities:

macula_root (application supervisor)
 macula_routing_server (Kademlia DHT)
 macula_nat_system (NAT traversal)
 macula_bootstrap_system (mesh discovery)
 macula_gateway_system (QUIC transport)
 macula_bridge_system (hierarchical mesh)
 macula_platform_system (CRDT coordination)
 macula_registry_system (package distribution)
 macula_content_system (P2P content transfer)
 macula_dist_system (Erlang distribution)

ProjectDescription
macula-ecosystemDocumentation hub
macula-consoleManagement console
bc-gitopsGitOps reconciler
macula-tweannNeuroevolution framework

Community


License

Apache 2.0 - See LICENSE for details.


Built with the BEAM