p2p-messenger

A serverless, end-to-end encrypted peer-to-peer messenger that combines WebRTC for low-latency P2P data transport with Nostr relays for decentralized signaling, peer discovery, and store-and-forward offline delivery.

2026Live1

A serverless, end-to-end encrypted peer-to-peer messenger that combines WebRTC for low-latency P2P data transport with Nostr relays for decentralized signaling, peer discovery, and store-and-forward offline delivery. It has zero vendor-controlled infrastructure -- users run their own relay or use public Nostr relays. The project ships with both a CLI (basic readline and a full-screen TUI built with React/ink) and a browser web client (Vite + React + Tailwind + Zustand). Both the CLI and web client are fully interoperable, sharing the same wire format and encryption protocols.

Stack

  • Language: TypeScript (strict mode, ES2022) across all packages
  • Monorepo tooling: pnpm workspaces
  • Web framework: React 19, React DOM 19
  • Web bundler: Vite 6 with @vitejs/plugin-react
  • CSS: Tailwind CSS 3.4 (dark-mode, custom peer accent colors)
  • State management (web): Zustand 5
  • CLI UI: ink 7 (React for terminal)
  • Crypto: @noble/ciphers (XChaCha20-Poly1305), @noble/curves (X25519, secp256k1), @noble/hashes (SHA-256, BLAKE3, HKDF-SHA256)
  • Nostr protocol: nostr-tools v2.23 (NIP-44, NIP-59 gift wrap, relay pool)
  • WebRTC: @roamhq/wrtc (Node WebRTC), browser native RTCPeerConnection
  • WebSocket: ws (both client and server)
  • Database (CLI): better-sqlite3 (message history persistence)
  • Database (web): idb-keyval (IndexedDB wrapper for identity, contacts, ratchet states, history)

Notable bits

The messenger implements Signal-grade cryptography including Double Ratchet for 1:1 offline messages, Sender Keys for group chats, and NIP-59 gift wrap for sender anonymity. It features hybrid P2P routing: WebRTC data channels when peers are online and connected, falling back to Nostr relays for offline delivery or when P2P is unavailable. File transfer uses chunked transfer with BLAKE3 Merkle root verification. The architecture is Nostr-native with multi-relay fan-out + subscription, NIP-05 identity resolution, presence events, and vector clock causal ordering. Two UI implementations are provided: a CLI TUI (React + ink) with split-pane scrollback, detached input, tab completion, and multi-window support; and a browser client (Vite + React + Tailwind + Zustand) with identity in IndexedDB, contact management, 1:1 chat, relay management, and settings panel.

Highlights

  • End-to-end encrypted with Signal-grade Double Ratchet and Sender Keys.
  • Hybrid P2P routing: WebRTC data channels + Nostr relays for offline delivery.
  • File transfer with chunked transfer and BLAKE3 Merkle root verification.
  • Nostr-native architecture with multi-relay fan-out and NIP-05 identity resolution.
  • Dual UI: CLI TUI (React/ink) and browser client (Vite+React+Tailwind+Zustand).
  • Offline-first with store-and-forward delivery via Nostr relays.

Links