What is OpenRTC?

A simpler way to connect browser, desktop, and mobile apps

OpenRTC helps browser, desktop, and mobile apps find each other and exchange data, audio, and video. Your application works with a small, familiar API while OpenRTC handles the connection system underneath it.

Without OpenRTC, a peer-to-peer feature usually needs a signaling service, presence tracking, authentication, NAT traversal, relay servers, reconnect logic, transport switching, encryption, and separate browser and native implementations. OpenRTC provides those shared pieces as one managed runtime.

The big picture

An OpenRTC feature has three parts:

  1. An avenue decides which peers are allowed to find each other. Use a device mesh, space, room, or ticket session.
  2. A connection represents one peer. It stays stable while OpenRTC repairs or changes the physical route underneath it.
  3. Messages, streams, and media carry your application data over that connection.
devices / space / room / ticket
              ↓
      one logical connection
              ↓
    message · stream · media
              ↓
  Iroh chooses and repairs the route

The route may use direct Iroh QUIC, an Iroh relay, WebRTC, or MoQ. Your message, stream, and media code stays the same when that route changes.

Start with one avenue

import { OpenRTC } from 'openrtc';

const rtc = OpenRTC({ apiKey: import.meta.env.VITE_OPENRTC_API_KEY });

const cursors = await rtc.spaces.join('portfolio-cursors', {
  payload: 'latest-state',
});

const position = cursors.state<{ x: number; y: number }>('position');

position.watch(({ peerId, value }) => {
  renderRemoteCursor(peerId, value);
});

position.set({ x: 120, y: 80 });

await cursors.leave();
await rtc.close();

Constructing the client performs no network, storage, auth, timer, WASM, or transport work. The first avenue you start activates only that feature.

Choose the smallest surface

Product needCapabilityDefault behavior
Signed-in users with several devicesrtc.devices.start()Persistent device identity; connect only to online devices
Live cursors or an art experiencertc.spaces.join()Session identity and live-only membership
A match, call, or collaboration sessionrtc.rooms.join()Ephemeral membership
A bounded handoff sessionrtc.tickets.issue()Ephemeral, device-bound capability

Each active avenue exposes its own peers, channels, diagnostics, and connections. Closing the handle ends only that feature.

Use the connection

For small structured values, send a message:

room.onConnection((connection) => {
  connection.onMessage((message) => console.log(message));
  void connection.send({ type: 'hello' });
});

For a long or large flow, open a stream. For camera and microphone tracks, use the media API. OpenRTC applies avenue scope, admission, encryption, recovery, and current-route checks before application data is delivered.

Durable membership, relay use, managed attestation, MoQ, and BLE require both portal enablement and an explicit runtime request. Rooms default to auto: mesh through eight members and eligible sparse latest-state fan-out through 50. Managed and authority modes fail closed until their security, capacity, and pricing gates pass.

Responsibility boundary

Your app owns login UX, its identity provider, product authorization, and platform-attestation registration. OpenRTC validates registered assertions or managed evidence, binds a per-install device key, issues scoped grants, enforces revocation and budgets, and meters OpenRTC usage credits.

OpenRTC does not require consumer apps to configure its Firebase project, database, storage, gateway URL, or internal app identifiers.

See Avenues for the complete TypeScript and Rust decision guide, including defaults, lifecycle, usage behavior, and examples for every avenue.

See Media, streams, and datagrams for the connection data APIs, and Advanced native for pure Rust and Tauri applications.

Specialized protocols

  • openrtc-netcode owns matches and replicated/latest state.
  • openrtc-file-transfer owns bounded transfer protocol behavior.
  • y-openrtc connects Yjs to an already activated room handle.
  • openrtc/runtime is reserved for low-level adapters and specialized protocol integration.