Client SDK JS
npx @buildinternet/releases get livekit-client-sdk-jsnpx @buildinternet/releases get livekit-client-sdk-jsfix: add code 1000 to onclose handler in WebSocketStream - #2086 (@phaitonican)
fix: don't reset mid track map on publisher answers with empty map - #2089 (@lukasIO)
Support simulcast for svc codecs (vp9/av1) - #2083 (@cnderrauber)
Fix the subscriber silently buffering remote ICE candidates after a reconnect - #2054 (@xianshijing-lk)
triggerIceRestart put the subscriber into restartingIce on every reconnect, but only
setRemoteDescription clears that — and the server re-offers the subscriber only when the
reconnect moved the participant to a different node. After an ordinary signal-only resume no
offer arrives, so the flag stayed set for the lifetime of the transport and every subsequent
remote candidate was queued instead of applied, leaving the subscriber unable to adopt any new
network path the server proposed. The subscriber no longer enters that state: the server does
not send candidates ahead of the offer that introduces them, so queueing them gains nothing.
fix: ensure buffered events are flushed on signal reconnection - #2044 (@lukasIO)
fix: error on datastreams when chunks are missing - #2073 (@lukasIO)
Forward DisconnectReason to the ParticipantDisconnected event - #2055 (@seonghunYang)
fix: enqueue signal requests until queue has been drained - #2061 (@lukasIO)
Add roomOptions.dataStream.maxPayloadByteLength to control max data stream size - #2060 (@1egoman)
Fix supportsAdaptiveStream always returning true by comparing typeof against the 'undefined' string. It now returns false in environments without ResizeObserver or IntersectionObserver. - #2059 (@mrpmohiburrahman)
Treat TokenSource JWTs without exp as expired, and still honor exp when nbf is absent - #2057 (@SashaMIT)
Convert internal exports to be external in examples/demo - #2067 (@1egoman)
Decode text data streams without TextDecoder fatal mode for broader runtime support - #2037 (@JoelTowell)
fix: ensure buffered events are flushed on signal reconnection - #2043 (@lukasIO)
fix: cancel pending onTrack callbacks when subscription fails - #2019 (@lukasIO)
fix: match opus fmtp parameters by exact token and look up the opus codec case-insensitively when munging SDP - #2036 (@lukasIO)
Only run the TrackEvent.TimeSyncUpdate animation frame loop while something is subscribed to the event, and clear the frame handle when a track's monitor is stopped so the loop can be restarted - #2038 (@U-OK)
fix: emit TrackStreamStateChanged again by reading the previous stream state before overwriting it - #2039 (@tomkail)
Apply the resolved degradation preference to the backup codec's sender - #2040 (@xianshijing-lk)
Degradation preference is a property of the sender, not of the track, and a backup codec publishes over its own sender. Previously only the primary sender was configured, so the backup encoder resolved a preference implicitly and could adapt along a different axis than the primary.
fix: recover broken publish paths — act on local ConnectionQuality.Lost, recreate the peer connection when an ICE restart has no remote description, bound how long a transport may stay connecting, and reconnect (instead of disconnecting) on a detected connection state mismatch - #2030 (@lukasIO)
fix: enable Terser mangle.safari10 to fix scoping issues for variables in react-native - #2028 (@davidliu)
fix: ensure dd extension also for recvonly - #2052 (@lukasIO)
fix: emit events that were buffered during resume after declaring the room as reconnected - #2018 (@lukasIO)
Ensure empty error reasons use fallback notation - #1999 (@lukasIO)
Remove stale data track subscriber handles from the packet routing table - #2011 (@ladvoc)
Fix the reliable data channel dying under concurrent / multi-packet writes (#1995). Data-channel sends now use two-watermark flow control (fill up to a high-water mark, resume when drained to a low-water mark) and serialize contended senders through a per-kind lock, which prevents the SCTP send buffer from overflowing while keeping throughput saturated for data tracks. - #2013 (@1egoman)
Keep attached audio elements muted in startAudio() when webAudioMix is enabled, preventing double playback on platforms where element.volume has no effect (e.g. iOS Safari) - #2004 (@sawa-zen)
Add a localAudioTrack.applyConstraints method with a subset of AudioCaptureOptions - #2001 (@lukasIO)
Conform placeholder sections to the canonical fmtp for each shared payload - #1993 (@lukasIO)
Include the NonSharedUint8Array type polyfill in the published declarations. - #1997 (@1egoman)
The type was declared in an ambient .d.ts that was resolved during our own
build but never emitted to dist, so the published .d.ts files referenced a
type consumers could not resolve — surfacing as Cannot find name 'NonSharedUint8Array' under skipLibCheck: false and as Unable to follow symbol for "NonSharedUint8Array" in API Extractor (which broke downstream
packages such as @livekit/components-*). The polyfill is now an exported type
that is imported explicitly wherever it is used, so it ships in dist and the
published types type-check standalone.
Add support for user_data frame metadata trailer type - #1983 (@chenosaurus)
Properly handle maxPayloadLength of 0, upper bound maxMessageSize - #1966 (@1egoman)
Add restrictOwnAudio experimental param to AudioCaptureOptions - #1974 (@1egoman)
chore: add logging around signal connection closing for reconnections - #1980 (@lukasIO)
Enforce a maximum size of the sdp defined maxMessageSize on individual data packets sent via publishData - #1962 (@1egoman)
Add deployment to TokenSourceFetch options - #1971 (@lukasIO)
Skip pre-populated media sections for single peer connections on React Native - #1984 (@davidliu)
Ensure that sortPresets does NOT mutate values passed in via options into Room - #1979 (@1egoman)
fix: rtpMap event leak on multiple negotiations without video tracks - #1961 (@lukasIO)
Ensure clearTimeout(responseTimeoutId) is skipped when timeout isn't set yet - #1958 (@1egoman)
Send initial media sections with v1 signalling for FF - #1963 (@lukasIO)
Disable publisher offer with join in firefox - #1954 (@cnderrauber)
Fix memory leak where the constructor-registered devicechange listener on navigator.mediaDevices was not removed when a Room was constructed but never connected. The listener kept the Room instance reachable from the global navigator.mediaDevices EventTarget, defeating the FinalizationRegistry cleanup. - #1944 (@nikhilgupta58)
Ensure that client protocol is set in the dual peer connection case - #1942 (@1egoman)
Implement negotiation tracking based on offerId - #1927 (@lukasIO)
Ignore data track promise rejections after a subscription readable stream is discarded - #1917 (@1egoman)
chore: improve logging foundation for implicit context retrieval - #1907 (@lukasIO)
Pass optional LocalTrack reference to processors - #1916 (@lukasIO)
Ensure priority isn't set on all simulcast layers when using Firefox on iOS - #1920 (@lukasIO)
Defer onEnterPiP visibility update until after the next microtask and animation frame so Document Picture-in-Picture embedders can append DOM into the PiP window before isElementInPiP runs. - #1868 (@gparant)
Differentiate different 404 responses on validate path - #1901 (@lukasIO)
await screen share audio unpublish before returning setEnabled - #1899 (@lukasIO)
Avoid attaching a new Closing event listener for each waitForBufferStatusLow call - #1896 (@1egoman)
Re-compute encoding params after track replace - #1902 (@lukasIO)
Harden extension id computation and retry publishing on negotiation failure - #1895 (@lukasIO)
fix: ensure udpated tokens get set on the regionUrlProvider - #1900 (@lukasIO)
fix: handle race between LocalTrackSubscribed signal and publishTrack completion - #1872 (@pabloFuente)
Harden RemoteParticipant.dataTracks map to work when a data track subscription is processed before the room connect is complete - #1888 (@1egoman)
Update dependency webrtc-adapter to v9.0.5 - #1858 (@renovate)
Ensure transport manager is reset before attempting legacy fallback path - #1893 (@lukasIO)
Fix data tracks related subscript edge cases when the passed abort signal fires across the subscription lifecycle - #1892 (@1egoman)
Export CheckStatus as enum, not just type - #1855 (@Ludobaka)
fix: improve ordering of resolving waitForBufferStatus calls - #1877 (@lukasIO)
Close streamcontrollers when datatrack gets unpublished - #1879 (@lukasIO)
Moves "connected to Livekit Server" log within RTCEngine.join so it shows up for reconnects as well as connects - #1873 (@1egoman)
Send publisher offer with join request to accelerate connection - #1846 (@cnderrauber)
Enable E2EE key-size configuration via ExternalE2EEKeyProvider options - #1841 (@MariusBernhardt)
Ensure freshly created RTCEngine isn't recreated on join - #1843 (@lukasIO)
Fix shouldReturnCachedValueFromFetch check for cached options - #1837 (@lukasIO)
Add token fetch force option to skip TokenSource cache - #1839 (@lukasIO)
e2ee: ensure current key index isn't unintentionally updated - #1830 (@lukasIO)
Prevent unmute -> mute -> unmute cycle for track restarts that happen during unmute - #1793 (@mfairley)
Use controller.error to signal unexpected errors mid data stream - #1834 (@lukasIO)
Signal leave on failed connection attempts if signalling is connected - #1817 (@lukasIO)
Vendored ts-debounce and added critical timers to debounce function - #1800 (@mfairley)
Ensure cryptor setup respects async queue in worker - #1833 (@lukasIO)
Adds new OutgoingDataTrackManager to manage sending data track payloads - #1810 (@1egoman)
Ensure connection state mismatches aren't triggered for ongoing PC connection attempts - #1807 (@lukasIO)
Fix unnecessary track restarts on unmute when using ideal device constraints - #1794 (@mfairley)
Prevent ongoing renegotiations from declaring the negotiation as timed out - #1813 (@lukasIO)
Add data track packetizer and depacketizer implementations - #1798 (@1egoman)
Add missing type exports required by @livekit/components-core - #1815 (@1egoman)
Add data track packet serialization + deserialization logic - #1792 (@1egoman)
Update docs to clarify other client HKDF support - #1796 (@1egoman)
Add attachedStreamIds as text stream metadata - #1805 (@1egoman)
export type RoomEventCallbacks - #1599 (@shincurry)
Remove experimental tag on some stabilized features - #1777 (@lukasIO)
Fix connection check issues with pinned regions - #1775 (@lukasIO)
Control latency of lossy data channel - #1754 (@cnderrauber)
Add docs comments making it clear TokenSource-prefixed exported types shouldn't be used for TokenSource construction - #1776 (@1egoman)
Fix leaking memory by removing event listener from correct scope - #1768 (@wuhkuh)
Wait for dc buffer status low for all published packets - #1691 (@lukasIO)
Fix message loss during resuming/migration - #1757 (@cnderrauber)
Add connectionCount tracking and stop auto refetching after timeout - #1756 (@lukasIO)
Add explicit error types for future helper - #1753 (@lukasIO)
fix(LocalTrackAudio): prevent overwriting constraint flags - #1744 (@itamayo)
Keep text / byte stream handlers between room disconnects - #1741 (@1egoman)
Ensure unexpected websocket disconnects trigger reconnect flow - #1748 (@lukasIO)
Add exponential backoff strategy in case of connection failures - #1715 (@lukasIO)
Add participant as an optional parameter to EncryptionError events emitted on room level - #1723 (@CSantosM)
fix(e2ee): propagate worker data decryption errors and reject corresponding promises - #1729 (@CSantosM)
Fix potential undefined access while disconnecting - #1734 (@lukasIO)
Add new areTokenSourceFetchOptionsEqual function - #1733 (@1egoman)
Ensure publication isn't attempted after timeout rejected the promise - #1725 (@lukasIO)
Apply server supplied cache control settings for region url provider - #1669 (@lukasIO)
Only export types for TokenSource variants to try to push users to use the TokenSource.foo static constructors instead - #1707 (@1egoman)
Add check to ensure track visibility update only happens when adaptiveStream is enabled - #1712 (@1egoman)
Fix abort race resulting in multiple code paths trying to close the ws connection - #1695 (@lukasIO)
fix the RPC comment and clam the timeout if the provided value is less than 8s - #1694 (@xianshijing-lk)
Fix track mapping when single peer connectionis used - #1696 (@lukasIO)
Ensure leave requests can be sent before join response is received - #1687 (@lukasIO)
Increase RPC total timeout to 15s and connection timeout to 7s for better reliability under network latency. - #1692 (@xianshijing-lk)
Populate participant identity when receiving encrypted e2ee packets - #1679 (@lukasIO)
Export supportsAudioOutputSelection helper - #1676 (@lukasIO)
Fix bug in isResponseExpired token expiry checking logic - #1683 (@1egoman)
Use WebSocketStream for sequential signal processing - #1638 (@lukasIO)
Support for data channel encryption on React-Native - #1678 (@davidliu)
Add preliminary support for data message decryption - #1595 (@lukasIO)
Add video autoplay attributes to PublishVideoCheck - #1648 (@Doomann)
Ensure handleDisconnect is called also when already in Reconnecting state - #1671 (@lukasIO)
Fix TS 5.9 generic Uint8Array declaration when inferred - #1668 (@lukasIO)
Properly clean up event listeners in getNewAudioContext() - #1660 (@indexds)
Avoid uncaught errors related to send/disconnect races - #1674 (@bryfox)
Register online listener in engine's join - #1658 (@lukasIO)
add TokenSource token fetching abstraction - #1645 (@1egoman)
Ensure permission event is only emitted once for local participant - #1643 (@lukasIO)
internal typing fix - add missing async to postAction - #1644 (@1egoman)
Ensure mid is always interpreted as string - #1641 (@lukasIO)
Query audio track with all constraints present - #1624 (@lukasIO)
Ensure RemoteVideoTracks without any attached elements are stopped by adaptiveStream - #1625 (@lukasIO)
Disable av1 for firefox - #1631 (@cnderrauber)
Use SIF payload hashes to ensure integrity - #1629 (@lukasIO)
fix(e2ee): h264 publishing with e2ee enabled - #1632 (@lukasIO)
Check for encrypted track if room unencrypted, and if so, emit an event - #1627 (@1egoman)
feat: add ability to include an AbortSignal when reading from a datastream - #1611 (@1egoman)
Fix error when unwrapConstraint receives an empty deviceId when creating local tracks - #1594 (@mpnri)
feat(e2ee): add h265 as supported codec for encryption - #1618 (@lukasIO)
Handle numerous small data stream errors / state inconsistiencies with throwing explicit errors - #1613 (@1egoman)
lock all APIs that change underlying track with the same lock - #1620 (@lukasIO)
Fix iOS local track recorder mimetype for preconnect buffer - #1609 (@lukasIO)
Add support for react-native preconnect audio - #1598 (@davidliu)
Clear LocalParticipant futures at start of disconnect, not at end - #1604 (@1egoman)
fix: ensure audio output switching is disabled for safari based browsers - #1602 (@lukasIO)
skip errant signal layer leave message when already disconnected - #1601 (@1egoman)
fix: retry processor playback on abort error - #1592 (@lukasIO)
fix: correct handling of signal connect future - #1600 (@lukasIO)
allow manual controls even when adaptiveStream is enabled - #1569 (@davidzhao)
Add support for H265 - #1576 (@cnderrauber)
Ensure feature support checks include iOS checks - #1563 (@lukasIO)
Ensure encryption transforms are set up as soon as sender is created - #1561 (@lukasIO)
Fix transceiver reuse causing destination stream closed errors - #1554 (@lukasIO)
Stop MediaStream tracks at the end of the video check - #1552 (@svajunas-budrys)
disable dyncast for svc encoding - #1556 (@cnderrauber)
Update active device immediately for muted audio tracks - #1526 (@yashjain-99)
Drop outdated sdp answers and forward offer ids - #1547 (@lukasIO)
Improve e2e reliablility of data channel - #1546 (@cnderrauber)
do not expose token with Moved events - #1549 (@davidzhao)
fix: don't try to set audio output on Safari without explicit user interaction - #1527 (@lukasIO)
Fix svc encoding for safari 18.4 - #1519 (@cnderrauber)
feat: add MediaDeviceKind to media device error event - #1525 (@lukasIO)
fix: remove track from transceiver if add request failed - #1524 (@lukasIO)