Reconnection
The SDK handles transient network drops automatically. You don't need to write reconnect logic — just listen to the events.
Automatic Reconnect
When LiveKit detects a network interruption, the SDK transitions through:
connected → reconnecting → connected (success)
connected → reconnecting → disconnected (failure after retries)call.on('reconnecting', (attempt) => {
showBanner(`Connection lost — reconnecting (attempt ${attempt})`)
})
call.on('reconnected', () => {
hideBanner()
})
call.on('disconnected', (reason) => {
if (reason === 'networkError') {
showError('Could not reconnect. Please rejoin.')
}
})LiveKit's client SDK handles the underlying WebSocket and ICE renegotiation. The RTCstack SDK surfaces the events; LiveKit manages the retry timing (exponential backoff with jitter, configurable in livekit-client options).
Token Refresh on Reconnect
If the JWT is near expiry when a reconnect happens, the SDK calls tokenRefresher to get a fresh token before reconnecting. Wire it up at call creation:
const call = createCall({
token,
url,
tokenRefresher: async () => {
const res = await fetch('/api/refresh-token', { method: 'POST' })
const { token } = await res.json()
return token
},
})Without tokenRefresher, a reconnect attempt with an expired token will fail and emit disconnected.
Token Expiry
call.tokenExpiresAt // Date
call.on('tokenExpired', () => {
// Token is within the expiry window
// If tokenRefresher is set, the SDK handles this automatically
// Listen here only if you want to show a warning UI
})Connection State
call.connectionState
// 'idle' — createCall() called, connect() not yet called
// 'connecting' — connect() called, waiting for LiveKit
// 'connected' — active call
// 'reconnecting' — temporary drop, retrying
// 'disconnected' — call ended or unrecoverable errorDetecting Poor Connection
Per-participant connection quality is available:
call.participants.forEach((p) => {
console.log(p.name, p.connectionQuality)
// 'excellent' | 'good' | 'poor' | 'lost' | 'unknown'
})The local participant's quality is at:
call.localParticipant?.connectionQualityUse connectionQuality === 'poor' to show a warning icon in your UI.
Mobile Backgrounding
On iOS and Android, backgrounding a tab suspends WebSocket connections. The SDK will emit reconnecting when the tab comes back to the foreground. Surface a non-intrusive indicator so users know the call is recovering.
call.on('reconnecting', () => {
// Show: "Reconnecting..."
})
call.on('reconnected', () => {
// Hide indicator
})
