Skip to main content
GenosRTC is the integrated peer-to-peer communication module within GenosDB, providing a high-level, robust, and decentralized framework for real-time applications directly in the browser.

Core Architectural Principles

Decentralization First

Data and media exchange occurs directly between peers with no central bottleneck

Simplicity through Abstraction

Clean event-driven API hides WebRTC complexity

Room-Based Scoping

Logical “rooms” provide natural containers for peer groups

Secure by Design

Built-in E2E encryption for signaling and data channels

Architectural Components

1. Signaling Layer (Peer Discovery)

GenosRTC uses the decentralized Nostr network for signaling instead of custom WebSocket servers. Relay Selection Strategy:
1

Immediate Connection

Connects instantly to developer-provided or built-in relays for zero-latency startup
2

Dynamic Fallback

Loads extended relay list from local cache (updated from nostr.watch) and schedules background connections
3

Adaptive Management

Automatically disconnects from non-performant relays (e.g., those requiring Proof-of-Work)
Configuration:
// Use built-in relays (instant)
const db = await gdb('mydb', { rtc: true });

// Custom relay list
const db = await gdb('mydb', {
  rtc: {
    relayUrls: [
      'wss://relay1.example.com',
      'wss://relay2.example.com'
    ]
  }
});
See Nostr Signaling Guide for running your own relay.

2. P2P Transport Layer (WebRTC)

Manages direct, low-latency RTCPeerConnections between peers:
  • WebRTC ICE Framework: Traverses NATs and firewalls using STUN/TURN
  • Encrypted by Default: DTLS-SRTP encryption for all data/media
  • Direct Connections: Peer-to-peer links minimize latency

3. Session Management (The Room)

The db.room object orchestrates the P2P session lifecycle:
const room = db.room;

// Listen for peers
room.on('peer:join', (peerId) => {
  console.log('Peer joined:', peerId);
});

room.on('peer:leave', (peerId) => {
  console.log('Peer left:', peerId);
});

// Get connected peers
const peers = room.getPeers();

4. Communication Abstractions

Data Channels

Built on RTCDataChannel for structured data:
// Send GenosDB operations
syncChannel.send({
  type: 'operation',
  data: { /* ... */ }
});

// Create custom channels
const chatChannel = room.channel('chat');
chatChannel.on('message', (data, fromPeer) => {
  console.log('Chat from', fromPeer, ':', data);
});

chatChannel.send({ text: 'Hello!' });

Media Streams

Optimized for real-time audio/video:
// Add local media stream
const stream = await navigator.mediaDevices.getUserMedia({
  video: true,
  audio: true
});

room.addStream(stream);

// Receive remote streams
room.on('stream', (stream, peerId) => {
  const video = document.getElementById('remote-video');
  video.srcObject = stream;
});

Lifecycle of a Peer Connection

1

Initialization

Client instantiates GDB with rtc: true, joining a specific room
2

Discovery

Connects to Nostr network and subscribes to room topic
3

Signaling Handshake

Exchanges connection offers, answers, and ICE candidates via Nostr
4

Direct Connection

Establishes RTCPeerConnection (signaling relay no longer needed)
5

Communication

Uses Data Channels and Media Streams for direct peer-to-peer exchange
6

Disconnection

On leaving, peer:leave event broadcasts and connections tear down

Cellular Mesh Architecture

For large-scale applications (100+ peers), GenosRTC offers an optional Cellular Mesh Overlay:
const db = await gdb('mydb', {
  rtc: {
    cells: true  // Enable cellular mesh
  }
});
See Cellular Mesh for complete details. Key Benefits:
  • Reduces connections from O(N²) to O(N)
  • Supports 10,000+ peers
  • ~log(N) hop latency vs. single-hop traditional mesh
  • Automatic cell sizing and bridge selection

Security Model

All WebRTC communications are encrypted using DTLS (data) and SRTP (media), preventing eavesdropping on P2P links.
Optional password parameter encrypts all signaling and data channel messages:
const db = await gdb('mydb', {
  rtc: {
    password: 'my-secret-key'
  }
});
Even Nostr relays cannot decipher the application’s data.
In cellular mode, inter-cell messages maintain encryption. Bridge nodes forward encrypted payloads without accessing plaintext.

Performance Characteristics

MetricTraditional MeshCellular Mesh
Connections/peerO(N)O(√N)
Message latency1 hop~log(N) hops
Max practical peers~100Massive scale
Bandwidth/peerHighOptimized

Complete Example

import { gdb } from 'genosdb';

async function startP2PApp() {
  // Initialize with RTC
  const db = await gdb('my-collaborative-app', {
    rtc: {
      cells: { cellSize: 'auto' } // Enable cellular mesh
    }
  });

  const room = db.room;
  const selfId = db.selfId;

  // Listen for peers
  room.on('peer:join', (peerId) => {
    console.log(`Peer ${peerId} joined`);
    updatePeerList();
  });

  room.on('peer:leave', (peerId) => {
    console.log(`Peer ${peerId} left`);
    updatePeerList();
  });

  // Data sync happens automatically via GenosDB
  // But you can also use custom channels
  const chat = room.channel('chat');
  
  chat.on('message', (data, fromPeer) => {
    displayMessage(fromPeer, data.text);
  });

  document.getElementById('sendBtn').onclick = () => {
    const text = document.getElementById('input').value;
    chat.send({ text, author: selfId });
    displayMessage('You', text);
  };

  function updatePeerList() {
    const peers = room.getPeers();
    document.getElementById('peerCount').textContent = Object.keys(peers).length;
  }

  updatePeerList();
}

startP2PApp();

Nostr Signaling

Run your own Nostr relay

Cellular Mesh

Scalable mesh architecture

Fallback Server

Optional reliability enhancement

Build docs developers (and LLMs) love