{"id":12207,"library":"twilio-video","title":"Twilio Video JavaScript SDK","description":"The `twilio-video` package provides a JavaScript library for adding real-time voice and video communication capabilities to web applications. It enables developers to build multi-party video experiences, leveraging Twilio's infrastructure for signaling and media routing. The current stable version is 2.34.0, released in January 2026, with a rapid release cadence that often includes multiple updates per quarter. Key features include support for real-time transcriptions, enhanced telemetry for monitoring `RTCPeerConnection` states and application lifecycle, Document Picture-in-Picture API integration, and beta features like WebRTC overrides for optimized environments and Video Processor V3 for advanced media manipulation. It differentiates itself by offering a complete WebRTC abstraction layer integrated with the broader Twilio ecosystem, providing robust cross-browser compatibility and handling complex networking challenges inherent in real-time communication.","status":"active","version":"2.34.0","language":"javascript","source_language":"en","source_url":"https://github.com/twilio/twilio-video.js","tags":["javascript","twilio","webrtc","library","video","rooms","typescript"],"install":[{"cmd":"npm install twilio-video","lang":"bash","label":"npm"},{"cmd":"yarn add twilio-video","lang":"bash","label":"yarn"},{"cmd":"pnpm add twilio-video","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"This is the standard ESM way to import the primary connection function. While `require` works in CommonJS, modern Node.js and browser environments favor ESM imports.","wrong":"const { connect } = require('twilio-video');","symbol":"connect","correct":"import { connect } from 'twilio-video';"},{"note":"Imports all exports into a namespace object `Video`. There is no default export, so `import Video from 'twilio-video'` would fail. Useful for accessing various modules like `Video.connect` and for type imports in TypeScript.","wrong":"import Video from 'twilio-video';","symbol":"Video (namespace)","correct":"import * as Video from 'twilio-video';"},{"note":"This is the CommonJS syntax for Node.js environments or older browser build setups. If using in a modern ESM-only Node.js project or browser, prefer `import * as Video from 'twilio-video';`.","wrong":"import { Video } from 'twilio-video';","symbol":"Video (CommonJS)","correct":"const Video = require('twilio-video');"},{"note":"For importing only TypeScript types without pulling in runtime values, useful with `isolatedModules` or when types are distinct from runtime values.","wrong":"import { RemoteParticipant } from 'twilio-video';","symbol":"RemoteParticipant (type)","correct":"import type { RemoteParticipant } from 'twilio-video';"}],"quickstart":{"code":"import { connect, Room, LocalParticipant, RemoteParticipant } from 'twilio-video';\n\n// Replace with your actual Access Token and Room Name\nconst accessToken = process.env.TWILIO_ACCESS_TOKEN ?? ''; // Use environment variable or fetch from a server\nconst roomName = 'my-super-secret-room';\n\nif (!accessToken) {\n  console.error('TWILIO_ACCESS_TOKEN environment variable is not set. Please provide a valid access token.');\n  // In a real application, you might redirect the user or show an error message.\n} else {\n  connect(accessToken, { name: roomName }).then(room => {\n    console.log(`Connected to Room \"${room.name}\"`);\n\n    // Handle existing participants in the room\n    room.participants.forEach(participantConnected);\n    // Listen for new participants connecting\n    room.on('participantConnected', participantConnected);\n\n    // Handle participants disconnecting\n    room.on('participantDisconnected', participantDisconnected);\n    // Handle disconnection from the room itself\n    room.once('disconnected', error => {\n      console.log('Disconnected from Room:', error);\n      room.participants.forEach(participantDisconnected);\n    });\n  }).catch(error => {\n    console.error('Failed to connect to Twilio Video Room:', error);\n  });\n}\n\nfunction participantConnected(participant: RemoteParticipant) {\n  console.log(`Participant \"${participant.identity}\" connected`);\n\n  const div = document.createElement('div');\n  div.id = participant.sid;\n  div.innerText = participant.identity;\n  document.body.appendChild(div); // Append to body to visualize participants\n\n  // When a participant publishes a track, attach it to the DOM\n  participant.on('trackSubscribed', track => trackSubscribed(div, track));\n  // Attach already subscribed tracks\n  participant.tracks.forEach(publication => {\n    if (publication.isSubscribed) {\n      trackSubscribed(div, publication.track);\n    }\n  });\n}\n\nfunction participantDisconnected(participant: RemoteParticipant) {\n  console.log(`Participant \"${participant.identity}\" disconnected`);\n  document.getElementById(participant.sid)?.remove(); // Remove participant's div from DOM\n}\n\nfunction trackSubscribed(div: HTMLDivElement, track: any) {\n  // Attach the audio/video track to the participant's div element\n  div.appendChild(track.attach());\n}","lang":"typescript","description":"This quickstart demonstrates how to connect to a Twilio Video Room, handle participant connections and disconnections, and attach their video and audio tracks to the DOM. It assumes you have a valid Twilio Access Token."},"warnings":[{"fix":"Upgrade your Node.js environment to version 22 or newer to ensure compatibility.","message":"The `twilio-video` library now requires Node.js version 22 or higher. Deployments or development environments using earlier Node.js versions will fail.","severity":"breaking","affected_versions":">=2.34.0"},{"fix":"Upgrade to `twilio-video@2.32.1` or newer to resolve SDP negotiation issues and ensure compatibility with recent Chrome versions.","message":"Applications running `twilio-video` versions older than 2.32.1 may experience SDP negotiation failures with Chrome 137+ due to duplicated payload types generated by SDP munging. This can prevent participants from connecting or exchanging media.","severity":"breaking","affected_versions":"<2.32.1"},{"fix":"Upgrade to `twilio-video@2.28.2` or newer to ensure correct `MediaStreamTrack` cloning behavior across Safari and iOS browsers, preserving the original disabled state.","message":"Cloning a disabled `MediaStreamTrack` in Desktop Safari 18 and iOS browsers on iOS 18 would incorrectly set the `enabled` property to `true` in versions prior to 2.28.2, deviating from the MediaStreamTrack specification.","severity":"gotcha","affected_versions":"<2.28.2"},{"fix":"Exercise caution when implementing beta features in production environments. Monitor changelogs for updates and potential breaking changes related to these APIs, and be prepared for adjustments.","message":"Features such as Video Processor V3 and WebRTC Overrides are currently in beta. Their APIs and underlying behaviors are subject to change without a major version bump, and may not be stable for production use.","severity":"gotcha","affected_versions":">=2.29.0"},{"fix":"For modern browser and Node.js applications, prefer `import { connect } from 'twilio-video';`. If supporting older Node.js or build processes, ensure your tooling correctly handles CommonJS modules.","message":"While CommonJS `require` syntax is supported, modern JavaScript applications and build tools increasingly default to ESM `import` syntax. Using `require` in an ESM-only context without proper transpilation or bundling can lead to module resolution errors.","severity":"gotcha","affected_versions":"*"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"For modern browser/ESM environments, use `import { connect } from 'twilio-video';`. If using the CDN script tag, access via `const Video = Twilio.Video;`. Ensure your module system matches your import/require style.","cause":"This typically occurs when trying to use a CommonJS `require` syntax (`const Video = require('twilio-video');`) in a browser environment or an ESM-only Node.js project without proper transpilation or bundling.","error":"TypeError: Video.connect is not a function"},{"fix":"Ensure you are on `twilio-video@2.32.1` or newer. Verify network connectivity, the validity of your Twilio Access Token, and the correctness of the room name. Check the browser console for more specific WebRTC errors.","cause":"This generic WebRTC error can stem from various issues, including incompatible SDP generated by older `twilio-video` versions interacting with newer browser WebRTC implementations (e.g., the Chrome 137+ SDP munging bug).","error":"Unhandled Promise Rejection: AbortError: Failed to set remote answer SDP: Failed to set remote answer sdp. Cannot set SDP offer."},{"fix":"Ensure `twilio-video` is correctly installed. Since the library ships its own types, you typically don't need `@types/twilio-video`. Check your `tsconfig.json` to ensure `node_modules` is included in `typeRoots` or `include` paths, and consider setting `esModuleInterop` to `true` if mixing module styles.","cause":"The TypeScript compiler is unable to locate the type definitions for the `twilio-video` package.","error":"TS2307: Cannot find module 'twilio-video' or its corresponding type declarations."},{"fix":"For browser environments, use the CDN build (which exposes `Twilio.Video` globally) or a bundler like Webpack/Rollup configured for ESM. For ESM Node.js, use `import { connect } from 'twilio-video';`.","cause":"This error occurs when `require()` is called in a browser environment, or in a Node.js environment configured exclusively for ECMAScript Modules (ESM) without a CommonJS fallback mechanism.","error":"ReferenceError: require is not defined"},{"fix":"Upgrade to `twilio-video@2.32.1` or newer to resolve this issue and ensure video tracks remain active when viewed in Picture-in-Picture windows.","cause":"A bug in earlier `twilio-video` versions would cause video tracks to be automatically switched off by `Client Track Switch Off Control` even when they were visible and rendered in a Document Picture-in-Picture window.","error":"Video track freezes when video element is offscreen in a Document Picture-in-Picture window."}],"ecosystem":"npm"}