Always connects
When a direct WebRTC path is blocked, Dendri falls back through STUN, then TURN, then an encrypted TLS relay. The connection just happens.
Presence, cursors, chat, video, and live document sync over peer-to-peer WebRTC. One small SDK, any framework, your server.
// npm install @afterrealism/dendri-client
import { createDendriStore }
from "@afterrealism/dendri-client";
const room = createDendriStore({
url: "wss://signal.example.com", // yours
});
room.join("design-review");
room.broadcast({ cursor: { x, y } });
// every peer sees it, instantly
One createDendriStore() call gives you rooms, presence, and messaging, with drop-in bindings for React, Vue, and Svelte.
After the handshake, data flows directly between peers. Nobody meters your messages, because nobody carries them.
The server is open source and yours to run. Prefer zero ops? Point the same SDK at a hosted endpoint instead.
Reconnection, NAT traversal, encryption, and document sync are built in, not homework.
When a direct WebRTC path is blocked, Dendri falls back through STUN, then TURN, then an encrypted TLS relay. The connection just happens.
On the last tier, payloads are sealed with ECDH and AES-GCM before they touch the server. It relays bytes it cannot read.
Star-topology rooms with host migration and typed presence for every peer.
Media calls ride the same room primitives as data.
A first-class CRDT provider for collaborative editing.
Exponential backoff, offline queueing, seamless resume.
Eleven demos, every one deployed against the production stack. Open one in two tabs, watch them sync, then read the source.
Three more live at collaborative-layers, react-basic, and vue-basic. All examples on GitHub β
No backend to write, no protocol to learn. The store is the whole API surface for most apps.
Add the framework-neutral client to your app.
npm install @afterrealism/dendri-client
Point it at your server. That's the whole config.
createDendriStore({ url, apiKey })
Join a room and broadcast. Peers update live.
room.join("lobby")
Production-grade P2P signaling: the layer between a weekend library and a full video platform.
Cursors, presence, and Yjs document sync for whiteboards, editors, and design tools. Rooms and presence are first-class, not an add-on.
Collaborative editing guide βHost authority, deterministic host migration, and typed RPC between peers. Close the host tab and the game keeps running.
Play the live demo βFiles move directly between browsers. When the relay tier kicks in, payloads stay sealed end to end; the server cannot read them.
Try the live demo βThe API will feel familiar: connect(), call(), the same events. You gain reconnection that keeps your ID, transport fallback, and a maintained server.
Read the migration guide βAn honest map of the landscape. Sometimes another tool is the right call.
| Dendri | PeerJS | Liveblocks / PartyKit | LiveKit / Daily | |
|---|---|---|---|---|
| Model | Self-host-first P2P signaling | Library + best-effort free cloud | Hosted collaboration SaaS | Managed video platform (SFU) |
| Rooms & presence | Built in | None | Built in | Built in |
| Connection fallback | P2P, STUN, TURN, encrypted relay | None | Server-relayed by design | SFU-routed by design |
| Pricing model | Free self-host; flat hosted tiers | Free | Usage-based | Per participant-minute |
| Sweet spot | Data rooms up to 50 peers; video calls 2-6 | Demos and prototypes | Hosted collab apps | Large video conferences |
Building 10+ person video conferences? That is SFU territory: LiveKit or Daily will serve you better.
The server is open source and free forever. Hosted tiers give you a managed endpoint and an API key.
Open source, your infrastructure
Managed signaling & TURN
Production workloads
After checkout your API key arrives by email. Manage it in the dashboard.
Yes. The client SDKs (@afterrealism/dendri-client, @afterrealism/dendri-y) are Apache-2.0: embed them in anything, closed source included. AGPL-3.0 covers only the signaling server: run it freely, and if you modify it and offer it as a network service, publish those modifications. Your application code never inherits AGPL. A commercial server license is available for closed-source hosted use.
You can self-host the open-source server, or use the hosted tier. Either way the SDK ships no default endpoint: every app points at a URL you configure, so there is no hidden dependency on anyone's infrastructure.
Connections fall back through STUN, TURN, and an end-to-end encrypted TLS relay. Signaling itself falls back from WebSocket to SSE to long-polling. If the browser can reach the web, Dendri connects.
On the P2P tiers it never sees payloads. On the relay tier, payloads are sealed in the browser with ECDH and AES-GCM before they leave; the server relays bytes it cannot decrypt.
Rooms are star-topology: the host fans out to everyone else. Data rooms hold up to 50 peers by default (configurable with --max_room_size); for video calls plan for 2 to 6 peers. Beyond that you want an SFU platform, not P2P.
Only for the strictest networks. The server mints short-lived TURN credentials when started with --turn-secret (enable fetchTurnCredentials in the client), and the hosted tier includes managed TURN.
Start free with the open-source server, or grab a hosted key and skip the infrastructure entirely.