The web is the network

Serverless WebRTC for JavaScript apps

Trystero helps browsers discover each other and communicate directly with peer-to-peer data, files, audio, video, and presence. No accounts. No signaling server to deploy. Just import and connect.

Get the code
npm i trystero

What is Trystero?

Trystero is an open source JavaScript library that makes WebRTC peer discovery and peer-to-peer communication feel simple. Use it to build multiplayer web apps, collaborative tools, browser-to-browser file transfer, video chat, local-first sync, and realtime presence without running your own matchmaking infrastructure.

Connect in a few lines

Import Trystero, join a room, and start sending peer-to-peer messages. Peers find each other automatically through serverless signaling.

// Import Trystero
import {joinRoom} from 'trystero'

// Join a room with your app ID and a room ID
const room = joinRoom(
  {appId: 'my-app'},
  'room-id'
)

let peerCount = 0

// Handle when a peer joins
room.onPeerJoin = peerId => {
  console.log(`${peerId} joined!`)
  peerCount++
}

Simple WebRTC peer discovery

Trystero abstracts away all the complexity of WebRTC and peer discovery. Send files, video streams, and any other data with a clean and easy API.

Encrypted peer-to-peer data

All data sent between peers is end-to-end encrypted. No intermediary can read your users’ messages. You can opt into more advanced identity verification features too.

Flexible signaling strategies

Peers discover each other through decentralized infrastructure like Nostr, MQTT, BitTorrent, and more. You can also run your own relay if you’re into that kind of thing.

Send data, files, and realtime events

Actions are typed channels. Create as many as you need. Send strings, objects, binary data like files, or audio/video streams.

// Create an action to send and receive cursor positions
const cursor = room.makeAction('cursor')

// Send the cursor position to peers when the mouse moves
document.onmousemove = e =>
  cursor.send({x: e.clientX, y: e.clientY})

// Receive the cursor position from other peers
cursor.onMessage = (pos, {peerId}) =>
  movePeerCursor(peerId, pos)

// Using TypeScript? Add a type
type CursorPosition = {x: number; y: number}
const typedCursor =
  room.makeAction<CursorPosition>('cursor-typed')

Build peer-to-peer audio and video apps

Stream audio and video directly between browsers. Build presence indicators, voice chat, or collaborative editing.

// Grab the user's camera stream
const stream = await navigator.mediaDevices.getUserMedia({
  audio: true,
  video: true
})

// Send the stream to peers in the room
room.addStream(stream)

// Send the stream to peers who join later
room.onPeerJoin = peerId => {
  room.addStream(stream, {target: peerId})
}

// Handle streams from other peers
room.onPeerStream = (stream, peerId) =>
  // Connect the stream to a video element
  videoElements[peerId].srcObject = stream

Ask peers for answers

Actions can also work like request/response channels. Ask one peer for a value, wait for a reply, or collect answers from a whole room.

// Create a request/response action
const availability = room.makeAction('availability', {
  kind: 'request',
  onRequest: ({date}) => calendar.isFree(date)
})

// Ask a specific peer and wait for their answer
const isFree = await availability.request(
  {date: '2026-05-04'},
  {
    target: teammateId,
    timeoutMs: 1000
  }
)

if (isFree) {
  showAvailable(teammateId)
}

Start building

Trystero is open source, works across modern browsers and devices, and is ready to use in JavaScript and TypeScript projects.