{"id":11242,"library":"livekit-client","title":"LiveKit Client SDK","description":"The `livekit-client` package provides a JavaScript/TypeScript SDK for building real-time communication applications featuring video, audio, and data. It connects to LiveKit Cloud or self-hosted LiveKit servers, enabling developers to integrate functionalities like multi-modal AI, live streaming, and video calls. The current stable version is 2.18.3, with a release cadence featuring frequent patch updates and minor versions typically every one to two weeks. Key differentiators include its focus on performance optimizations like adaptive streaming and dynacast, robust event-driven architecture, and comprehensive support for various media types and advanced features like End-to-End Encryption (E2EE) and data tracks, offering a powerful platform for interactive media applications.","status":"active","version":"2.18.3","language":"javascript","source_language":"en","source_url":"ssh://git@github.com/livekit/client-sdk-js","tags":["javascript","typescript"],"install":[{"cmd":"npm install livekit-client","lang":"bash","label":"npm"},{"cmd":"yarn add livekit-client","lang":"bash","label":"yarn"},{"cmd":"pnpm add livekit-client","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Type definitions for WebRTC Media Capture and Streams API extensions for recording. Required for proper TypeScript support in environments leveraging advanced media recording features, but often not a direct runtime dependency.","package":"@types/dom-mediacapture-record","optional":true}],"imports":[{"note":"The primary class for managing real-time connections. While named import is standard for ESM, CommonJS environments typically use `const livekit = require('livekit-client'); const room = new livekit.Room();`.","wrong":"const Room = require('livekit-client').Room;","symbol":"Room","correct":"import { Room } from 'livekit-client';"},{"note":"An enum defining all events dispatched by the `Room` object. For CommonJS, access via `livekit.RoomEvent` after `const livekit = require('livekit-client');`.","wrong":"const RoomEvent = require('livekit-client').RoomEvent;","symbol":"RoomEvent","correct":"import { RoomEvent } from 'livekit-client';"},{"note":"A utility object containing predefined video resolutions and settings. Use named imports for ESM. For CommonJS, access as `livekit.VideoPresets`.","wrong":"const VideoPresets = require('livekit-client').VideoPresets;","symbol":"VideoPresets","correct":"import { VideoPresets } from 'livekit-client';"}],"quickstart":{"code":"import {\n  LocalParticipant,\n  LocalTrackPublication,\n  Participant,\n  RemoteParticipant,\n  RemoteTrack,\n  RemoteTrackPublication,\n  Room,\n  RoomEvent,\n  Track,\n  VideoPresets,\n} from 'livekit-client';\n\nasync function setupLiveKitRoom() {\n  const url = process.env.LIVEKIT_URL ?? 'ws://localhost:7800'; // Replace with your LiveKit server URL\n  const token = process.env.LIVEKIT_TOKEN ?? 'YOUR_LIVEKIT_TOKEN'; // Replace with your LiveKit access token\n\n  if (token === 'YOUR_LIVEKIT_TOKEN') {\n    console.error('Please provide a LiveKit access token. You can generate one from your LiveKit server or dashboard.');\n    return;\n  }\n\n  const room = new Room({\n    adaptiveStream: true,\n    dynacast: true,\n    videoCaptureDefaults: {\n      resolution: VideoPresets.h720.resolution,\n    },\n  });\n\n  // Ensure a parent element exists to attach video/audio streams\n  const parentElement = document.getElementById('livekit-container') || document.body;\n\n  room.on(RoomEvent.TrackSubscribed, (track: RemoteTrack, publication: RemoteTrackPublication, participant: RemoteParticipant) => {\n    if (track.kind === Track.Kind.Video || track.kind === Track.Kind.Audio) {\n      const element = track.attach();\n      parentElement.appendChild(element);\n      console.log(`Track subscribed: ${track.kind} from ${participant.identity}`);\n    }\n  });\n\n  room.on(RoomEvent.TrackUnsubscribed, (track: RemoteTrack, publication: RemoteTrackPublication, participant: RemoteParticipant) => {\n    const element = track.detach();\n    element.remove();\n    console.log(`Track unsubscribed: ${track.kind} from ${participant.identity}`);\n  });\n\n  room.on(RoomEvent.ActiveSpeakersChanged, (speakers: Participant[]) => {\n    console.log('Active speakers:', speakers.map(s => s.identity));\n  });\n\n  room.on(RoomEvent.Disconnected, (reason: string | undefined) => {\n    console.log('Disconnected from room:', reason);\n  });\n\n  room.on(RoomEvent.LocalTrackUnpublished, (publication: LocalTrackPublication, participant: LocalParticipant) => {\n    console.log('Local track unpublished:', publication.trackSid);\n  });\n\n  console.log('Preparing connection...');\n  room.prepareConnection(url, token);\n\n  try {\n    await room.connect(url, token);\n    console.log('Connected to room:', room.name);\n    await room.localParticipant.enableCameraAndMicrophone();\n    console.log('Published local camera and microphone.');\n  } catch (error) {\n    console.error('Failed to connect to LiveKit room:', error);\n  }\n}\n\n// Call the setup function when the DOM is ready in a browser environment\nif (typeof document !== 'undefined') {\n  document.addEventListener('DOMContentLoaded', setupLiveKitRoom);\n} else {\n  // Fallback for non-browser environments or immediate execution\n  setupLiveKitRoom();\n}","lang":"typescript","description":"This quickstart demonstrates how to connect to a LiveKit room, handle remote participant track subscriptions, publish local camera and microphone, and manage room events, suitable for browser-based applications."},"warnings":[{"fix":"Review the LiveKit client SDK v1 to v2 migration guide at https://docs.livekit.io/recipes/migrate-from-v1/ and update your code accordingly.","message":"Migrating from v1.x to v2.x involves breaking changes. Consult the official migration guide for a detailed overview of what has changed.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Update any custom log parsers or monitoring tools that specifically look for `pID` in LiveKit client logs to use `participantID` instead.","message":"The log context field `pID` was renamed to `participantID` for consistency and clarity in logging. This affects how participant identifiers appear in internal logs.","severity":"breaking","affected_versions":">=2.18.0"},{"fix":"Always call `room.prepareConnection(url, token)` proactively to optimize connection latency, even if the user hasn't initiated the call yet.","message":"Calling `room.prepareConnection(url, token)` as early as possible (e.g., when the page loads) can significantly speed up the actual `room.connect()` time by pre-warming WebRTC resources.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Refer to the LiveKit E2EE documentation for proper setup, ensuring correct key provisioning and compatible server-side configurations. Test thoroughly in your target environment.","message":"End-to-End Encryption (E2EE) requires careful setup, including key management and server-side configuration, to ensure secure communication. Misconfiguration can lead to failed connections or unencrypted streams.","severity":"gotcha","affected_versions":">=2.16.0"},{"fix":"Monitor network performance and behavior after updating to ensure compatibility. If issues arise, review LiveKit documentation on WebRTC connection paths and configuration options.","message":"LiveKit client v2.17.0 introduced a new default RTC path that uses a single peer connection mode, falling back to the legacy dual peer connection mode if necessary. This change aims to improve performance but might alter network behavior for some setups.","severity":"gotcha","affected_versions":">=2.17.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Replace `const livekit = require('livekit-client');` with `import * as livekit from 'livekit-client';` or use named imports like `import { Room } from 'livekit-client';`.","cause":"Attempting to use CommonJS `require()` syntax in an ECMAScript Module (ESM) context (e.g., in a modern React or Vue project without a proper build setup for CJS).","error":"ReferenceError: require is not defined"},{"fix":"Ensure your token generation logic is correct, the token includes the required `RoomJoin` grant, and the token has not expired. Regenerate the token and verify server-side configuration.","cause":"The LiveKit access token provided is expired, malformed, or does not grant the necessary permissions for the requested room and participant identity.","error":"Failed to connect to room: Invalid token"},{"fix":"Ensure your application is served over HTTPS. Prompt the user for media permissions and provide UI guidance. Check browser and operating system privacy settings for camera/microphone access.","cause":"The browser has denied access to the user's camera or microphone. This can be due to user choice, insecure context (non-HTTPS), or system-level permissions.","error":"DOMException: Permission denied"},{"fix":"If using CommonJS, ensure you are accessing `Room` correctly (e.g., `const livekit = require('livekit-client'); const room = new livekit.Room();`). If using a script tag, ensure the global `LivekitClient` object is loaded and use `new LivekitClient.Room()`.","cause":"When using `require('livekit-client')` in CommonJS, if the module's export structure doesn't expose `Room` directly as a property, or if the global `LivekitClient` object is not available in a script tag setup.","error":"TypeError: livekit.Room is not a constructor"}],"ecosystem":"npm"}