Events
The SDK uses a typed event emitter. All events are strongly typed — TypeScript will catch incorrect handler signatures at compile time.
Subscribing
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.
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.
call.on('participantJoined', (participant: Participant) => {})participantLeft
A remote participant disconnected.
call.on('participantLeft', (participant: Participant) => {})activeSpeakerChanged
The list of currently speaking participants changed.
call.on('activeSpeakerChanged', (speakers: Participant[]) => {})messageReceived
A chat message arrived.
call.on('messageReceived', (message: Message) => {
// message: { id, from, text, timestamp, to? }
})reactionReceived
An emoji reaction was sent.
call.on('reactionReceived', (from: string, emoji: string) => {})reconnecting
The SDK lost connection and is attempting to reconnect. attempt starts at 1.
call.on('reconnecting', (attempt: number) => {
showToast(`Reconnecting... attempt ${attempt}`)
})reconnected
Successfully reconnected after a drop.
call.on('reconnected', () => {
hideToast()
})disconnected
The call ended — either by calling call.disconnect(), being kicked, or an unrecoverable error.
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.
call.on('tokenExpired', () => {
showWarning('Your session is expiring soon')
})devicesChanged
The user's available media devices changed (device plugged in/removed).
call.on('devicesChanged', (devices: DeviceList) => {
// devices: { audioinput, audiooutput, videoinput }
updateDeviceSelectors(devices)
})Participant Shape
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
}
