Your users want a room.
Not a loading spinner.

Dendri adds presence, chat, and live sync to your app with reliable peer-to-peer connections and one open-source SDK.

room.ts 2 peers connected
import { createDendriStore }
  from "@afterrealism/dendri-client";

const room = createDendriStore({
  url: "wss://signal.example.com",
  enableRelay: true
});

room.join("design-review");
room.broadcast(
  { x: 120, y: 84 },
  { topic: "cursor" }
);
// Your endpoint. Never a hidden default.

What Dendri gives you

One join, a live room

Discovery, host election, presence, and messaging arrive together. You build the experience, not the bookkeeping.

A data path you control

Use direct P2P for payload traffic, or enable room relay when reachability matters more. Either way, there is no per-message bill.

An exit built in

Your endpoint, your server, your data path. The open-source stack has no paid tier and no vendor lock-in.

The demo took an afternoon.
Production took the calendar.

The room works until a laptop sleeps, a network changes, or the host leaves. That is the work Dendri takes off your plate.

The network changes.

A VPN, strict NAT, or hotel Wi-Fi turns a perfect demo into a connection error.

The connection finds another way.

Dendri falls back from P2P through STUN and TURN to a TLS relay. Signaling can bridge WebSocket, SSE, and long-poll.

P2P STUN TURN TLS relay

The host closes the tab.

Your users should not lose the room because one person finished first.

The room keeps moving.

Deterministic host migration promotes another peer. Token-based reconnection, heartbeat, and offline message queuing help interrupted peers resume.

A new person joins.

They need to find the room, see who is there, and start taking part.

The room introduces itself.

Rooms, typed presence, topics, RPC, and acknowledgements are first-class APIs. For shared documents, the Dendri Yjs provider handles synchronization.

Do not take the story's word for it.

Open a demo in two tabs. The moment either works or it does not.

Your first room is three steps away.

No protocol to invent and no account to create. Start locally, then deploy the same open-source stack.

Start building →
  1. Get your endpoint

    Launch Redis and the Rust server with the quickstart, then verify it is alive.

    curl http://127.0.0.1:9876/health
  2. Add the client

    Install the framework-neutral SDK in your app.

    npm install @afterrealism/dendri-client
  3. Open the room

    Point at your endpoint, join, and open a second tab.

    room.join("design-review")

The room is yours.
So is the way out.

Every feature ships in the open-source binary you deploy. There is no paid tier, no feature gate, and no default connection to our infrastructure.

Signaling server
AGPL-3.0
Client and Yjs SDKs
Apache-2.0
Hosted account
Not required
Usage metering
None

Know where Dendri fits.

A useful guide tells you when to choose another path.

DendriPeerJSLiveblocks / PartyKitLiveKit / Daily
ModelSelf-hosted P2P signalingLibrary + best-effort free cloudHosted collaboration SaaSManaged video platform
Rooms & presenceBuilt inNoneBuilt inBuilt in
Connection fallbackP2P, STUN, TURN, TLS relayNoneServer-relayed by designSFU-routed by design
Sweet spotData rooms up to 50 peers; video calls 2 to 6Demos and prototypesHosted collaboration appsLarge video conferences

Building 10+ person video conferences? LiveKit or Daily will serve you better.

Questions before your first room.

Can I use the SDK in a commercial app?

Yes. The client SDKs are Apache-2.0, closed-source apps included. AGPL-3.0 covers only the signaling server. If you modify that server and offer it as a network service, publish those modifications. Your application code never inherits AGPL.

Do I have to run my own server?

Yes. The open-source server runs anywhere from a small VPS to Kubernetes. The SDK ships no default endpoint: every app points at a URL you configure, so there is no hidden dependency on anyone's infrastructure.

What happens on hostile networks?

Connections fall back through STUN, TURN, and a TLS relay when those options are enabled. Signaling itself falls back from WebSocket to SSE to long-polling.

Can the server read my data?

With relay disabled, direct P2P payloads stay off the server. With Room enableRelay: true, every room broadcast is also sent to your server, even when WebRTC is open, and is visible as application data. For 1:1 JSON-safe traffic, HybridConnection with encryptRelay: true seals relay payloads with ECDH and AES-GCM.

How many peers can share a room?

Rooms use 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, choose an SFU platform.

Do I need to set up TURN?

Only for the strictest networks. The server mints short-lived TURN credentials when started with --turn-secret. Enable fetchTurnCredentials in the client. The self-hosting guide covers running coturn alongside it.

Build the moment they came for.

Start with one room. Open two tabs. Watch your app come alive.