Migrating from Twilio Video to Agora’s React JS SDK

Published in
6 min readMay 8, 2024


This guide is meant to assist developers migrating their existing Twilio Video implementation using React JS to the Agora Video React JS SDK. If you are initiating a new project, please refer to the Agora Video React JS SDK documentation.

A quick start demo for Agora with React JS can be found here on Github (Quick Start Demo). Additional demos can be found here: More Demos.

Check out api-ref.agora.io to view the full React JS SDK documentation.

Step 1: Obtain Agora Video SDK Keys

To access Agora services and integrate them into your project, follow these steps to obtain the necessary information from the Agora Console:

  1. App ID
    — Log in to the Agora Console and navigate to your project.
    — Find the “App ID,” a randomly generated string unique to your App. This ID is crucial for identifying your application within Agora.
  2. Temporary Token
    — When clients from your App join a channel, they need a Token for authentication.
    — Generate a temporary Token from the Agora Console, which has a validity period of 24 hours. This Token is used to authenticate users joining your channel.
  3. Channel Name:
    — Define a unique string as the “Channel Name” to identify and label your channel.

Step 2: Install Agora Video SDK

Use npm, pnpm or yarn

# with npm
npm i agora-rtc-react
# or with pnpm
pnpm add agora-rtc-react
# or with yarn
yarn add agora-rtc-react

Remove Twilio SDK from your project:

npm uninstall twilio-video`

Step 3: Create Client and RTC Provider

The Agora React SDK uses hooks and components to simplify the integration of Agora’s Video features into a React web app. To ensure that the hooks and components are using the same client, a client is created with useRTCClient and passed to the AgoraRTCProvider

import AgoraRTC { useRTCClient } from "agora-rtc-react"

// Initialize Agora Client
const client = = useRTCClient(
codec: “vp8”,
mode: “rtc”

return () => {
<AgoraRTCProvider client={client}>
{/* Video Call Components that use the common client context */}

The useRTCClient hook can be used to retrieve the client object from the AgoraRTCProvider context

const client = = useRTCClient()

Step 4: Start and Join Sessions


// Twilio Video import as alias
import * as TwilioVideo from 'twilio-video'

var twilioVideo = TwilioVideo
var twilioRoom

twilioRoom = await twilioVideo.connect(TOKEN, { name: 'yourName', audio: false, video: false, dominantSpeaker: true })


The useJoin hook lets a user automatically join a channel when the component is ready and automatically leaves the channel when the component is unmounted.

import { useJoin } from "agora-rtc-react"

// Join the channel
appid: 'AppID',
channel: 'ChannelName'!,
token: 'TOKEN',
uid: 0

Step 5: Create Local Audio / Video Tracks and Publish


<div class="video-container-div" width="1920" height="1080"></div>
// video
let localVideoTrack = await twilioVideo.createLocalVideoTrack({
height: { ideal: 720, min: 480, max: 1080 },
width: { ideal: 1280, min: 640, max: 1920 },
aspectRatio: 16/9,

const localMediaContainer = document.getElementById('video-container-div')

// audio
let localAudioTrack = await twilioVideo.createLocalAudioTrack()

const audioElement = localAudioTrack.attach();


  • useLocalMicrophoneTrack:This hook lets you create a local camera video track.
  • useLocalCameraTrack:Create a local video track using the video captured by the local camera.
  • usePublish: This hook automatically publishes the local tracks when the component is ready and un-publishes them when the component is unmounted.
  • LocalVideoTrack: This component plays the camera video track and the microphone audio track of the local user
  • LocalUser This component plays the local video track
import { 
} from "agora-rtc-react"

// get local microphone and camera
const { localMicrophoneTrack } = useLocalMicrophoneTrack();
const { localCameraTrack } = useLocalCameraTrack();

// Publish local microphone and camera
usePublish([localMicrophoneTrack, localCameraTrack]);

// Play local video using components
return () => {
// Option 1: <LocalVideoTrack />
<LocalVideoTrack track={localCameraTrack} play />

// Option 2: <LocalUser />

Step 6: Unpublish and Destroy Tracks


Twilio Video/Audio is track-based, requiring looping through each video/audio track to unpublish the video/audio

   twilioRoom.localParticipant.videoTracks.forEach((publication) => {
var selfTwilioVideo = document.getElementById('video-container-div')

twilioRoom.localParticipant.audioTracks.forEach((publication) => {


Like Twilio’s Video/Audio, Agora’s Video/Audio is also track based. Once a track has been published with usePublish you can un-publish the tracks in two ways: automatically when the component using usePublish is unmounted; or manually without having to unmount the component.

   await client.unpublish();                                       // Unpublish all tracks at once
await client.unpublish(localCameraTrack); // Unpublish 1 track
await client.unpublish([localAudioTrack, localCameraTrack]); // Unpublish specific set of tracks
// Track destruction:

Note on unpublish:

This methods can be called multiple times. You can use `publish` and `unpublish` to manage the publication and unpublishing of specific local tracks.

This method is asynchronous and should be used with `Promise` or `async/await`.

Step 8: Render Remote User Video


In Twilio, you might have used participantConnected and trackSubscribed event listeners.

<div class="remote-video-container" width="1920" height="1080"></div>
   twilioRoom.on('participantConnected', (participant) => {
participant.on('trackSubscribed', (track) => {
// a user turned on their video, render it

participant.on('trackUnsubscribed', (track) => {
// a user turned off their video, stop rendering it
var selfTwilioVideo = document.getElementById('remote-video-container')


Once a remote user successfully publishes audio/video tracks, the SDK adds the remote user to it’s list of remote users. Retrieve the list of remote users with the useRemoteUsers hook, and use the RemoteUser component to subscribe and play the remote user’s audio and video tracks.

   const remoteUsers = useRemoteUsers();

return (
<div id='remote-video-container'>
// Initialize each remote stream using RemoteUser component
remoteUsers.map((user) => (
<div key={user.uid} className="remote-video-container">
<RemoteUser user={user} />

Alternatively, you can use the useRemoteAudioTracks to automatically subscribe and retrieve the remote user’s audio and video tracks (respectively). When the component is unmounted the hook stops subscribing to the video tracks of the specified users.

   //remote users
const remoteUsers = useRemoteUsers();
const { audiotracks } = useRemoteAudioTracks(remoteUsers)
const { videotracks } = useRemoteVideoTracks(remoteUsers)

return (

You can selectively retrieve the remote tracks of a specific user with useRemoteUserTrack.

   //remote users
const remoteUsers = useRemoteUsers();
const audiotrack = useRemoteUserTrack(remoteUsers[0], 'audio')
const videotracks = useRemoteUserTrack(remoteUsers[0], 'video')

return (

Step 9: Leave and End Sessions




he Agora React SDK makes it very simple to leave a channel. When the component that calls useJoin unmounts, the Agora client will automatically leave the channel.

To manually leave the channel use client.leave(), the SDK immediately destroys objects related to the current channel, including subscribed remote user objects, remote track objects, and objects recording connection status. To rejoin the channel, call join after calling leave.

await client.leave();

Additional Agora Video SDK Features

The Agora Video React SDK provides a rich set of features that can enhance your video conferencing application. Here are some key features and information to consider:

  1. Platform Support: Agora Video SDKs support a variety of platforms, including Android, iOS, Web, Linux, macOS, and Windows. Additionally, it offers wrappers for popular frameworks like Flutter and React Native.
  2. Cloud Recording: Agora provides cloud recording capabilities for their Video SDKs, allowing you to capture and store your sessions for later playback or archival purposes. Consult the Agora Video SDK documentation for details on implementing this feature.
  3. Screen Sharing: Implement screen sharing in your application using Agora’s screen-sharing capabilities. This feature is valuable for collaborative work and presentations.
  4. Plug-in Architecture: Agora’s support for plug-ins enhances the extensibility of your video application. You can seamlessly integrate additional functionalities or customize features by leveraging Agora’s plug-in architecture.
  5. Tree-Shaking: Agora’s React Video SDK for React supports tree-shaking, enabling you to optimize your application’s bundle size by eliminating unused code during the build process. This ensures that your application remains lightweight and performs efficiently.
  6. Secure Communication: Agora’s end-to-end encryption ensures that the communication between users in a session is highly secure. This feature enhances privacy and protects sensitive information exchanged during video conferences.

For comprehensive details on Agora Video React SDK features and how to implement them, refer to the Agora Video React SDK Documentation.

Explore the full potential of Agora Video React SDK to create a robust and feature-rich video conferencing experience. If you have specific feature requirements, consult the documentation for guidance on implementation.




Director of DevRel @ Agora.io … former CTO @ webXR.tools & AR Engineer @ Blippar — If you can close your eyes & picture it, I can find a way to build it