A relay doesn't need to read a message to forward it

MeshWhisper is messaging infrastructure built on this observation. Encrypted on the device. Forwarded as an opaque blob. Decrypted on the other end. The relay never holds a key. It doesn't need to.

Relay promiscuously. Connect selectively.
MeshWhisper
Node layer — live now

The backbone

One Docker container. Packet relay, store-and-forward, push notifications, media storage, and a prekey directory. Always on. Always connectable. Never holds a decryption key.

How the node works →
Device layer — roadmap

The mesh

Every device running any SDK-embedded app is a potential relay for every other. The relay infrastructure is shared across all participating applications. The relay mesh is shared. The application namespaces are isolated.

Read more →
Stage 1 — Now

First relay node live

The first relay is running at relay.meshwhisper.org. Prudence — the reference PWA built on the SDK — is live and open to use.

Try Prudence →
Stage 2

Developer adoption

Other developers deploy nodes. Multi-node privacy routing becomes real — no single operator sees both ends of a conversation. The bootstrap operator's share shrinks.

Stage 3

Mesh density

Device-layer relay becomes meaningful. Privacy strengthens automatically as a side effect of adoption — the inverse of centralised messaging.

Reference app — live now

Prudence

A fully working encrypted messenger built entirely on the MeshWhisper SDK. No phone number. No email. Username and password — your keys are derived from them, nothing is stored on a server. Messages are end-to-end encrypted before they leave your device.

Open Prudence
prudence.meshwhisper.org
Hey — can you read this?
Only me. The relay can't.
That's the point.
PQXDH + Double Ratchet · No keys on server · Works in any browser

Integrate the SDK

Use the relay at wss://relay.meshwhisper.org during development. Deploy your own node in production.

1. Install
$ npm install @meshwhisper/sdk
2. Initialize
import { MeshWhisper } from '@meshwhisper/sdk';

const mw = await MeshWhisper.init(({
  namespace: 'com.example.myapp',
  node: 'wss://relay.meshwhisper.org',
  onMessage: (msg) => display(msg),
});

// PQXDH key exchange happens automatically on first contact
await MeshWhisper.send(contactId, payload);
3. Deploy your node
$ docker run -d \
  -v meshwhisper_data:/data \
  -e BASE_URL=https://relay.myapp.com \
  ghcr.io/meshwhisper/node:latest

Learn by reading real code

Four working integrations, each maintained as a living reference for SDK adopters. None are slides; all are git clone away.

PWA

Prudence

A complete PWA covering every SDK feature — DMs, groups, media, push, multi-device archive sync, conversation history recovery. The cross-reference doc maps each SDK feature to the file where it's wired.

prudence/REFERENCE.md →
AI agent

support-bot

A customer-service agent running as a MeshWhisper peer. ~150 lines, two modes (echo + LLM-backed with streaming replies). The relay sees only ciphertext; the agent's process sees plaintext.

examples/support-bot →
Compliance

supervised-chat

"The supervisor can read every chat" without breaking E2EE. Three actors plus a Vite + React + FlexSearch dashboard for browsing the audit log. Supervisor reads via group membership, not a backdoor.

examples/supervised-chat →
End-to-end

ticket-lifecycle

LLM triage front-line with tool-use-driven escalation to a supervised human handoff. The closest thing to a real customer-service product running on MeshWhisper, composed from the previous two examples.

examples/ticket-lifecycle →
Multi-device

linked-devices

Signal-style multi-device pairing in ~200 lines. A secondary device mints a link offer (render as QR / paste / deep link); the primary accepts; both share an account afterward. Demonstrates the createDeviceLinkOffer / acceptDeviceLinkOffer / onDeviceLinked flow.

examples/linked-devices →
Verification

verification

Phone / email verification on top of the SDK. ~200 lines, single Node process, swappable SMS gateway. Backend issues a short-lived code; client verifies and claims the handle via setIdentifier. Includes an explicit security-considerations section.

examples/verification →