Running a node
UNAVI's networking runs on the iroh peer-to-peer network. Each running app is a peer, and a node is an always-on peer that runs without the app. A node hosts files for the wider network and can run UNAVI's discovery registry. Spaces live with the people in them, so a node does not keep a copy of every space it lists.
A node never opens a connection itself. Peers connect to it, and syncing and presence run over those connections, so the node has to be reachable from outside but never reaches out to peers that have gone away.
Set your domain
A node's identity is a did:web bound to a domain (see
Identity).
Set the domain with the UNAVI_DOMAIN environment variable.
It defaults to node.unavi.xyz, so set your own before running in
production.
Other peers resolve the node's identity by fetching
https://<domain>/.well-known/did.json.
The node's HTTP listener only binds to localhost.
Put a reverse proxy in front of it that terminates TLS (Transport Layer
Security) and forwards your domain to the node's port.
Run the node binary
unavi-node --port 5000| Flag | Effect |
|---|---|
--port <n> | HTTP port to listen on. Defaults to 5000. |
--data-dir <path> | Where keys, documents, hosted files, and registry.ron are stored. Defaults to the platform's data directory. |
--in-memory | Keep keys and documents in memory, and host no files. Useful for running several test nodes on one machine. |
--no-registry | Turn off the discovery registry. |
--debug | Verbose logging. |
Host files
Files placed in <data-dir>/files/ are pinned and served over iroh-blobs
when the node starts.
Subdirectories are included.
The node writes a files.json index alongside them, mapping each file
name to its content hash.
Point the app's asset manifest at that index to load exactly what your
node hosts.
Removing a file unpins it on the next start.
Configure the registry
People find spaces through the registry. It keeps a catalog of published spaces, curated views such as recent and featured, and live presence.
The registry's policy is set in registry.ron in your data directory,
which is read on every start.
(
allowlist: Some(["did:web:example.com"]),
featured: ["<namespace-id>"],
categories: ["social"],
)
The allowlist limits which DIDs can submit spaces to the catalog.
A missing file or field falls back to the open default.
Any authenticated DID can submit, nothing is featured, and no categories
are recognized.
The registry also enforces fixed limits so that one identity, or a crowd
of throwaway ones, can't fill it.
A did:key costs nothing to create, so all did:key identities share
one pool on top of the per-identity limits.
| Limit | Value |
|---|---|
| Listings per DID | 8 |
| Listings in the catalog | 10,000 |
Listings held by all did:key identities | 1,000 |
| Spaces one DID can be present in | 4 |
| Presences across the registry | 50,000 |
Presences held by all did:key identities | 2,000 |
| Occupants listed per space | 256 |
| Listing lifetime before it must be renewed | 30 days |
The active view only shows spaces that have a live listing, so presence in a space nobody listed doesn't appear there.