Skip to Content
Mux Docs: Home

Migrate to LiveKit Web SDK

Learn how to migrate your Mux Real-Time Video web application to LiveKit

Introduction to LiveKit

LiveKit provides real-time video services, including both an open-source stack and a cloud-hosted option, and will provide a simple integration with Mux to produce a Live Stream broadcast of any real-time video interactions.

When migrating from Mux Spaces to LiveKit you'll find most of the concepts are the same but there are a few terminology changes. We recommend using one of LiveKit's Server SDKs to manage any communication with LiveKit's API.


The LiveKit equivalent of a Space is called a Room. Rooms can be created manually or will be auto-created when the first participant joins. With LiveKit you must provide a unique name for the room.

One notable difference between Spaces and Rooms is the behavior of the auto subscription functionality. Spaces' automatic subscription mode works by subscribing to a maximum of 20 participants which have the highest priority server-side. LiveKit's behavior around automatic subscription will subscribe participants to every other participant.


The LiveKit equivalent of a Broadcast is called a Composite Recording.

LiveKit will provide a native integration with Mux to produce a Live Stream broadcast of any real-time video interactions. In the mean time you can also use Composite Recording to send an RTMP stream to Mux as a Live Stream.

Broadcast Layouts

LiveKit has their own built-in layouts for Composite Recordings but Mux is also open-sourcing the layouts we used for Broadcasts so you can use them within LiveKit. See the GitHub page muxinc/spaces-livekit-broadcast-layouts for more details

Construct a LiveKit JWT

JWTs are fundamental to using both Mux’s Real-Time Video & LiveKit but there are some major differences in their claim structure. See the LiveKit documentation for more details.

JWT Claims

expExpiration time of the tokenNo changes
issN/AAPI key ID used to issue this token
kidAPI Key ID used to sign this tokenN/A
subSpace IDUnique identity of the participant
participant_idUnique identity of the participantN/A
rolepublisher or subscriberN/A
metadataN/AParticipant metadata
video.roomN/Aname of room the participant will join
video.roomJoinN/Atrue if the participant is allowed to join the room
video.canPublishN/Atrue if the participant is allowed to publish media to the room
video.canSubscribeN/Atrue if the participant is allowed to subscribe to media in the room
video.canPublishDataN/Atrue if the participant is allowed to publish data (Equivalent to Mux's custom events) to the room
video.canUpdateOwnMetadataN/Atrue if the participant is allowed to update their own metadata (required for participant to set their own display name)

Example of a Publisher JWT

"exp": 1750137631,
"kid": "{ KEY ID HERE }",
"sub": "{ SPACE ID HERE }",
"aud": "rt",
"participant_id": "bob",
"role": "publisher"

Using the LiveKit Adapter

In order to make the transition to LiveKit easier we have created an adapter that will allow you continue using the Mux Spaces Web SDK while using LiveKit under the hood.

The adapter is not a long term solution and we recommend that you migrate to the LiveKit Web SDK as soon as possible.

Install the adapter

Update your package.json file to pull in the adapter using @mux/spaces-web as an alias so that you can continue to use the same import statements followed by an npm install.

"@mux/spaces-web": "npm:@mux/spaces-livekit-adapter@^0.1.9",

The only client side change you'll need to make is to update the Space constructor to tell it which LiveKit instance to use.

new Space(/* Your LiveKit JWT */, /* Your LiveKit URL */);

At this point your application should be using LiveKit under the hood & you can stop here. Continue reading when you want to migrate to the LiveKit Web SDK directly.

1Install the LiveKit Web SDK

yarn add livekit-client

2Update your imports

Replace instances in your imports of @mux/spaces-web with livekit-client, some of the types will not be found but we'll fix them in the following steps.

3Convert Space to Room

We'll begin the code migration by finding where the Space is first initialized & replace it with the equivalent new Room call. Before proceeding you'll need your updated JWT & your LiveKit URL. If you're using LiveKit Cloud you'll be provided one upon signing up, otherwise it'll be the URL where you're hosting LiveKit.

The call flow is roughly the same but with new Room() instead of new Space() and .connect() instead of .join(). Some parameters are also shifted from the Space constructor to the room connect method.

const space: Space = new Space(/* jwt: string */, /* options?: SpaceOptionsParams */);
const localParticipant = await space.join();

When calling join() using the Mux Spaces SDK any participants already in the room will trigger a ParticipantJoined event on the space object, but with LiveKit's SDK the existing participants will not trigger ParticipantConnected events. Instead of listening to an event you will need to trigger any handling of the existing participants by retrieving the list from room.participants.

4Participant changes

There are only minor differences between Mux's participant objects and LiveKit's.

connectionIdsid (Server ID)

5Track changes

Tracks are one of the areas where there's a conceptual difference between Mux Spaces & LiveKit. Mux has a single RemoteTrack class which may or may not be currently subscribed. LiveKit separates out the concept of the tracks that a participant is publishing from the tracks to which a LocalParticipant is subscribed. RemoteTrackPublication is object received when a RemoteParticipant publishes a track. A LiveKit RemoteTrack is the object available when the local participant is subscribed to that publication. The parameters for events around tracks can contain both a RemoteTrack & a RemoteTrackPublication, depending on what you're code depends on you may need one or both of these objects.

6Event changes

SpaceEvent to RoomEvent



StartedSpeakingIsSpeakingChanged(speaking: true)
StoppedSpeakingIsSpeakingChanged(speaking: false)

Translation Guide

Was this page helpful?