Skip to content

Events

The SDK uses a typed event emitter. All events are strongly typed — TypeScript will catch incorrect handler signatures at compile time.

Subscribing

ts
const call = createCall({ token, url })

call.on('connectionStateChanged', (state) => {
  // state: 'idle' | 'connecting' | 'connected' | 'reconnecting' | 'disconnected'
  console.log('Connection state:', state)
})

call.on('participantJoined', (participant) => {
  console.log(participant.name, 'joined')
})

// One-time listener
call.once('connected', () => {
  console.log('First connection established')
})

// Remove a specific listener
const handler = (p: Participant) => console.log(p.name)
call.on('participantJoined', handler)
call.off('participantJoined', handler)

// Remove all listeners for an event
call.removeAllListeners('participantLeft')

// Remove all listeners for all events
call.removeAllListeners()

Event Reference

connectionStateChanged

Fires whenever the connection state changes.

ts
call.on('connectionStateChanged', (state: ConnectionState) => {})
// 'idle' → 'connecting' → 'connected'
// 'connected' → 'reconnecting' → 'connected' (on drop+recover)
// 'connected' → 'disconnected' (on leave or fatal error)

participantJoined

A remote participant connected to the room.

ts
call.on('participantJoined', (participant: Participant) => {})

participantLeft

A remote participant disconnected.

ts
call.on('participantLeft', (participant: Participant) => {})

activeSpeakerChanged

The list of currently speaking participants changed.

ts
call.on('activeSpeakerChanged', (speakers: Participant[]) => {})

messageReceived

A chat message arrived.

ts
call.on('messageReceived', (message: Message) => {
  // message: { id, from, text, timestamp, to? }
})

reactionReceived

An emoji reaction was sent.

ts
call.on('reactionReceived', (from: string, emoji: string) => {})

reconnecting

The SDK lost connection and is attempting to reconnect. attempt starts at 1.

ts
call.on('reconnecting', (attempt: number) => {
  showToast(`Reconnecting... attempt ${attempt}`)
})

reconnected

Successfully reconnected after a drop.

ts
call.on('reconnected', () => {
  hideToast()
})

disconnected

The call ended — either by calling call.disconnect(), being kicked, or an unrecoverable error.

ts
call.on('disconnected', (reason: string) => {
  // reason: 'left' | 'kicked' | 'roomDeleted' | 'networkError' | ...
  navigateTo('/lobby')
})

tokenExpired

The JWT is within the expiry window. If tokenRefresher is configured, the SDK handles this automatically. Listen to this event if you want to show a "session expiring" warning.

ts
call.on('tokenExpired', () => {
  showWarning('Your session is expiring soon')
})

devicesChanged

The user's available media devices changed (device plugged in/removed).

ts
call.on('devicesChanged', (devices: DeviceList) => {
  // devices: { audioinput, audiooutput, videoinput }
  updateDeviceSelectors(devices)
})

Participant Shape

ts
interface Participant {
  id: string                  // LiveKit participant SID
  identity: string            // userId from token
  name: string
  isSpeaking: boolean
  isMicMuted: boolean
  isCameraMuted: boolean
  isScreenSharing: boolean
  role: ParticipantRole       // 'host' | 'moderator' | 'participant' | 'viewer'
  connectionQuality: ConnectionQuality  // 'excellent' | 'good' | 'poor' | 'lost' | 'unknown'
  audioTrack?: MediaStreamTrack
  videoTrack?: MediaStreamTrack
  screenTrack?: MediaStreamTrack
}