Docs

Actions send data between peers

Actions are named channels for your app. Use message actions for events and request actions when you need an answer from another peer.

Message actions

Message actions are good for presence, cursor movement, chat, document updates, multiplayer state, and fire-and-forget events.

type CursorMove = {x: number; y: number}

const cursor = room.makeAction<CursorMove>('cursor')

cursor.onMessage = (pos, {peerId}) => {
  movePeerCursor(peerId, pos)
}

document.onpointermove = e => {
  cursor.send({x: e.clientX, y: e.clientY})
}

Request actions

Request actions add response semantics on top of WebRTC data channels. Use them for availability checks, permission prompts, RPC-style calls, or asking a peer for current state.

const isEven = room.makeAction('is-even', {
  kind: 'request',
  onRequest: n => n % 2 === 0
})

const result = await isEven.request(42, {
  target: peerId,
  timeoutMs: 1000
})

Request many peers

Use requestMany() when a room has multiple peers that can answer independently.

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

const results = await availability.requestMany(
  {date: '2026-05-04'},
  {
    targets: teammateIds,
    timeoutMs: 1000,
    onResult: result => updateBadge(result)
  }
)