Realtime for your app, without the backend.

Presence, cursors, chat, video, and live document sync over peer-to-peer WebRTC. One small SDK, any framework, your server.

app.ts
// 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

Why Dendri

Ship it in an afternoon

One createDendriStore() call gives you rooms, presence, and messaging, with drop-in bindings for React, Vue, and Svelte.

No message tax

After the handshake, data flows directly between peers. Nobody meters your messages, because nobody carries them.

Your infrastructure

The server is open source and yours to run. Prefer zero ops? Point the same SDK at a hosted endpoint instead.

The hard parts, handled.

Reconnection, NAT traversal, encryption, and document sync are built in, not homework.

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.

End-to-end encrypted relay

On the last tier, payloads are sealed with ECDH and AES-GCM before they touch the server. It relays bytes it cannot read.

Rooms & presence

Star-topology rooms with host migration and typed presence for every peer.

Video & audio

Media calls ride the same room primitives as data.

Yjs document sync

A first-class CRDT provider for collaborative editing.

Auto-reconnect

Exponential backoff, offline queueing, seamless resume.

See it live, peer to peer.

Eleven demos, every one deployed against the production stack. Open one in two tabs, watch them sync, then read the source.

Chat & messaging

Typed messages fan out to the whole room.

Three steps to live.

No backend to write, no protocol to learn. The store is the whole API surface for most apps.

  1. Install

    Add the framework-neutral client to your app.

    npm install @afterrealism/dendri-client
  2. Connect

    Point it at your server. That's the whole config.

    createDendriStore({ url, apiKey })
  3. Build

    Join a room and broadcast. Peers update live.

    room.join("lobby")

Built for peer-to-peer work.

Production-grade P2P signaling: the layer between a weekend library and a full video platform.

Collaborative apps

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 β†’

Multiplayer games

Host authority, deterministic host migration, and typed RPC between peers. Close the host tab and the game keeps running.

Play the live demo β†’

Private file transfer

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 β†’

Coming from PeerJS

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 β†’

Where Dendri fits.

An honest map of the landscape. Sometimes another tool is the right call.

DendriPeerJSLiveblocks / PartyKitLiveKit / Daily
ModelSelf-host-first P2P signalingLibrary + best-effort free cloudHosted collaboration SaaSManaged video platform (SFU)
Rooms & presenceBuilt inNoneBuilt inBuilt in
Connection fallbackP2P, STUN, TURN, encrypted relayNoneServer-relayed by designSFU-routed by design
Pricing modelFree self-host; flat hosted tiersFreeUsage-basedPer participant-minute
Sweet spotData rooms up to 50 peers; video calls 2-6Demos and prototypesHosted collab appsLarge video conferences

Building 10+ person video conferences? That is SFU territory: LiveKit or Daily will serve you better.

Self-host free, or let us run it.

The server is open source and free forever. Hosted tiers give you a managed endpoint and an API key.

Self-host

$0

Open source, your infrastructure

  • Unlimited peers & rooms
  • Bring your own TURN
  • AGPL-3.0 server, Apache-2.0 SDK
  • Community support
Read the guide

Scale

$299/mo

Production workloads

  • 50,000 concurrent connections
  • 5 TB TURN bandwidth
  • Unlimited rooms & API keys
  • Dedicated Slack, 99.95% SLA
Start Scale

After checkout your API key arrives by email. Manage it in the dashboard.

Questions, answered.

Is the SDK license safe for commercial apps?

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.

Do I have to run my own server?

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.

What happens on hostile networks?

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.

Can the server read my data?

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.

How many peers can share a room?

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.

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), and the hosted tier includes managed TURN.

Add realtime today.

Start free with the open-source server, or grab a hosted key and skip the infrastructure entirely.