Twilio Video JavaScript SDK
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.
Common errors
-
TypeError: Video.connect is not a function
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.fixFor 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. -
Unhandled Promise Rejection: AbortError: Failed to set remote answer SDP: Failed to set remote answer sdp. Cannot set SDP offer.
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).fixEnsure 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. -
TS2307: Cannot find module 'twilio-video' or its corresponding type declarations.
cause The TypeScript compiler is unable to locate the type definitions for the `twilio-video` package.fixEnsure `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. -
ReferenceError: require is not defined
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.fixFor 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';`. -
Video track freezes when video element is offscreen in a Document Picture-in-Picture window.
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.fixUpgrade 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.
Warnings
- breaking The `twilio-video` library now requires Node.js version 22 or higher. Deployments or development environments using earlier Node.js versions will fail.
- breaking 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.
- gotcha 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.
- gotcha 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.
- gotcha 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.
Install
-
npm install twilio-video -
yarn add twilio-video -
pnpm add twilio-video
Imports
- connect
const { connect } = require('twilio-video');import { connect } from 'twilio-video'; - Video (namespace)
import Video from 'twilio-video';
import * as Video from 'twilio-video';
- Video (CommonJS)
import { Video } from 'twilio-video';const Video = require('twilio-video'); - RemoteParticipant (type)
import { RemoteParticipant } from 'twilio-video';import type { RemoteParticipant } from 'twilio-video';
Quickstart
import { connect, Room, LocalParticipant, RemoteParticipant } from 'twilio-video';
// Replace with your actual Access Token and Room Name
const accessToken = process.env.TWILIO_ACCESS_TOKEN ?? ''; // Use environment variable or fetch from a server
const roomName = 'my-super-secret-room';
if (!accessToken) {
console.error('TWILIO_ACCESS_TOKEN environment variable is not set. Please provide a valid access token.');
// In a real application, you might redirect the user or show an error message.
} else {
connect(accessToken, { name: roomName }).then(room => {
console.log(`Connected to Room "${room.name}"`);
// Handle existing participants in the room
room.participants.forEach(participantConnected);
// Listen for new participants connecting
room.on('participantConnected', participantConnected);
// Handle participants disconnecting
room.on('participantDisconnected', participantDisconnected);
// Handle disconnection from the room itself
room.once('disconnected', error => {
console.log('Disconnected from Room:', error);
room.participants.forEach(participantDisconnected);
});
}).catch(error => {
console.error('Failed to connect to Twilio Video Room:', error);
});
}
function participantConnected(participant: RemoteParticipant) {
console.log(`Participant "${participant.identity}" connected`);
const div = document.createElement('div');
div.id = participant.sid;
div.innerText = participant.identity;
document.body.appendChild(div); // Append to body to visualize participants
// When a participant publishes a track, attach it to the DOM
participant.on('trackSubscribed', track => trackSubscribed(div, track));
// Attach already subscribed tracks
participant.tracks.forEach(publication => {
if (publication.isSubscribed) {
trackSubscribed(div, publication.track);
}
});
}
function participantDisconnected(participant: RemoteParticipant) {
console.log(`Participant "${participant.identity}" disconnected`);
document.getElementById(participant.sid)?.remove(); // Remove participant's div from DOM
}
function trackSubscribed(div: HTMLDivElement, track: any) {
// Attach the audio/video track to the participant's div element
div.appendChild(track.attach());
}