---
"@context": https://schema.org
"@type": TechArticle
"@id": https://www.twilio.com/docs/video/node-getting-started#article
headline: Video Media SDK for Node.js quickstart
description: Connect to a Twilio Video Room from Node.js, publish a video track by pushing raw frames, and receive decoded frames from remote Participants.
url: https://www.twilio.com/docs/video/node-getting-started
inLanguage: en
dateModified: 2026-09-15T15:39:36.000Z
author:
  "@type": Organization
  name: Twilio Developer Education Team
publisher:
  "@type": Organization
  name: Twilio
---

# Video Media SDK for Node.js quickstart

This quickstart shows how to connect to a Video Room from a Node.js server, publish a video track by pushing raw frames, and receive decoded frames from remote Participants. To learn what the SDK is and how it differs from the client-side SDKs, see the [Overview][].

## Prerequisites

To use the Video Media SDK, you need the following prerequisites:

* [Create a Twilio account][].
* Install Node.js version 24.0.0 or later on Linux x64 or macOS x64. On an Apple Silicon Mac, run an x64 build of Node.js under Rosetta. To learn more, see [system requirements][].
* Create an API key SID and secret.

  #### View how to create an API Key

  ## Twilio Console

  1. Go to the [Twilio Console][1c]. The **Let's get building** page appears.
  2. Click **API keys and Auth tokens**. The **API keys & auth tokens** page appears with the **Auth Tokens** tab selected.
  3. Scroll to your **Account SID**.
  4. Click the copy button next to your **Account SID**.
  5. Run the following command, replacing `YOUR_ACCOUNT_SID` with *your* Account SID.

     ## macOS Terminal

     ```bash
     export TWILIO_ACCOUNT_SID=YOUR_ACCOUNT_SID
     ```

     ## Windows command line

     ```bash
     setx TWILIO_ACCOUNT_SID=YOUR_ACCOUNT_SID
     ```

     ## PowerShell

     ```bash
     [System.Environment]::SetEnvironmentVariable("TWILIO_ACCOUNT_SID", "YOUR_ACCOUNT_SID", "User")
     ```

     This command creates an environment variable on your development system for your account SID.
  6. To display the Auth Token, click the eye button in the **Primary auth token** box.
  7. Highlight and copy the Auth Token.
  8. Run the following command, replacing `YOUR_AUTH_TOKEN` with *your* Authentication Token.

     ## macOS Terminal

     ```bash
     export TWILIO_AUTH_TOKEN=YOUR_AUTH_TOKEN
     ```

     ## Windows command line

     ```bash
     setx TWILIO_AUTH_TOKEN=YOUR_AUTH_TOKEN
     ```

     ## PowerShell

     ```bash
     [System.Environment]::SetEnvironmentVariable("TWILIO_AUTH_TOKEN", "YOUR_AUTH_TOKEN", "User")
     ```

     This command creates an environment variable on your development system for your auth token.

  ## macOS Terminal

  ```bash
  export TWILIO_ACCOUNT_SID=YOUR_ACCOUNT_SID
  ```

  ## Windows command line

  ```bash
  setx TWILIO_ACCOUNT_SID=YOUR_ACCOUNT_SID
  ```

  ## PowerShell

  ```bash
  [System.Environment]::SetEnvironmentVariable("TWILIO_ACCOUNT_SID", "YOUR_ACCOUNT_SID", "User")
  ```

  ## macOS Terminal

  ```bash
  export TWILIO_AUTH_TOKEN=YOUR_AUTH_TOKEN
  ```

  ## Windows command line

  ```bash
  setx TWILIO_AUTH_TOKEN=YOUR_AUTH_TOKEN
  ```

  ## PowerShell

  ```bash
  [System.Environment]::SetEnvironmentVariable("TWILIO_AUTH_TOKEN", "YOUR_AUTH_TOKEN", "User")
  ```

  ## Legacy Console

  1. Go to the [Twilio Console][lc]. The **Get Started with Twilio** page appears.
  2. Scroll to the **Account Info** block.
  3. Click the copy button next to your **Account SID**.
  4. Run the following command, replacing `YOUR_ACCOUNT_SID` with *your* Account SID.

     ## macOS Terminal

     ```bash
     export TWILIO_ACCOUNT_SID=YOUR_ACCOUNT_SID
     ```

     ## Windows command line

     ```bash
     set TWILIO_ACCOUNT_SID=YOUR_ACCOUNT_SID
     ```

     ## PowerShell

     ```bash
     $Env:TWILIO_ACCOUNT_SID="YOUR_ACCOUNT_SID"
     ```
  5. Click the copy button next to your **Auth Token**.
  6. Run the following command, replacing `YOUR_AUTH_TOKEN` with *your* Authentication Token.

     ## macOS Terminal

     ```bash
     export TWILIO_AUTH_TOKEN=YOUR_AUTH_TOKEN
     ```

     ## Windows command line

     ```bash
     set TWILIO_AUTH_TOKEN=YOUR_AUTH_TOKEN
     ```

     ## PowerShell

     ```bash
     $Env:TWILIO_AUTH_TOKEN="YOUR_AUTH_TOKEN"
     ```

     This command creates an environment variable on your development system for your Authentication Token.

  ## macOS Terminal

  ```bash
  export TWILIO_ACCOUNT_SID=YOUR_ACCOUNT_SID
  ```

  ## Windows command line

  ```bash
  set TWILIO_ACCOUNT_SID=YOUR_ACCOUNT_SID
  ```

  ## PowerShell

  ```bash
  $Env:TWILIO_ACCOUNT_SID="YOUR_ACCOUNT_SID"
  ```

  ## macOS Terminal

  ```bash
  export TWILIO_AUTH_TOKEN=YOUR_AUTH_TOKEN
  ```

  ## Windows command line

  ```bash
  set TWILIO_AUTH_TOKEN=YOUR_AUTH_TOKEN
  ```

  ## PowerShell

  ```bash
  $Env:TWILIO_AUTH_TOKEN="YOUR_AUTH_TOKEN"
  ```

  [1c]: https://1console.twilio.com/go?to=/account/__account__

  [lc]: https://console.twilio.com

## Install the SDK

1. Install the SDK npm packages.
   ```bash
   npm install @twilio/video-node
   npm install @twilio/video-node-sdk
   ```
2. In your app, add the import statement for the SDK:
   ```javascript
   const { connect, createLocalVideoTrack } = require('@twilio/video-node-sdk');
   ```

## Create an Access Token

The `connect()` function takes a standard Twilio Video Access Token with a `VideoGrant`, the same token format the JavaScript SDK uses. [Generate an Access Token][] on your server with the [`twilio` helper library][].

```javascript title="Create an access token example"
const twilio = require('twilio');

function generateToken(identity, roomName) {
  const token = new twilio.jwt.AccessToken(
    process.env.TWILIO_ACCOUNT_SID,
    process.env.TWILIO_API_KEY,
    process.env.TWILIO_API_SECRET,
    { identity, ttl: 3600 },
  );
  token.addGrant(new twilio.jwt.AccessToken.VideoGrant({ room: roomName }));
  return token.toJwt();
}
```

> \[!WARNING]
>
> Keep your API key secret on the server. Never ship Twilio credentials in client-side code or commit the controls to source control.

## Connect to a Room

Create a local video track then pass it to `connect()`. The call resolves once the Room connects.

```javascript title="Connect to a Room example"
// !focus(3,5:8)
const { connect, createLocalVideoTrack } = require('@twilio/video-node-sdk');

const videoTrack = createLocalVideoTrack('virtual-camera');

const room = await connect(generateToken('node-participant', 'my-room'), {
  name: 'my-room',
  videoTracks: [videoTrack],
});

console.log('Connected to Room:', room.name, room.sid);
```

## Send video frames

Unlike the client-side SDKs, a local track lacks a camera. To supply raw [I420][] video frames, call the `write()` method on the track. Each call takes the `y`, `u`, and `v` planes as `Buffer` objects, along with their strides and the frame dimensions.

```javascript title="Send video example"
videoTrack.write({
  y: yPlane, // Buffer
  u: uPlane, // Buffer
  v: vPlane, // Buffer
  yStride: 1280,
  uStride: 640,
  vStride: 640,
  width: 1280,
  height: 720,
});
```

> \[!NOTE]
>
> Resolve  `connect()`, then send frames. Any frames before that resolution get dropped. Start your send loop after the `await` returns.

To learn about I420 video planes and strides and PCM audio, see [Work with media frames][].

## Receive media from remote Participants

Remote media arrives as raw decoded frames. Listen for `trackSubscribed`, then register an `onFrame()` callback on each video or audio track.

```javascript title="Receive media example"
function trackSubscribed(track) {
  if (track.kind === 'video') {
    track.onFrame(frame => {
      console.log(`Received ${frame.width}x${frame.height} frame`);
    });
  }
}

function participantConnected(participant) {
  participant.on('trackSubscribed', trackSubscribed);

  // A track can finish subscribing before this listener is attached.
  participant.tracks.forEach(publication => {
    if (publication.isSubscribed) {
      trackSubscribed(publication.track);
    }
  });
}

// participantConnected doesn't fire for Participants already in the Room, so
// seed from room.participants, then listen for Participants who join later.
room.participants.forEach(participantConnected);
room.on('participantConnected', participantConnected);
```

## Run a working example

The [SDK repository][] includes runnable examples. The [`virtual_camera.js`][] example decodes an MP4 with `ffmpeg` and sends its frames into a Room.

```bash
git clone https://github.com/twilio/twilio-video-node.git
cd twilio-video-node
cp .env.example .env
# Edit .env and set TWILIO_ACCOUNT_SID, TWILIO_API_KEY, and TWILIO_API_SECRET.
node examples/virtual_camera.js my-room
```

To review every example, see the [`examples` directory][].

## Next steps

* [Work with media frames][]: Learn the I420 video and PCM audio frame formats in depth.
* [Differences from the JavaScript SDK][]: Map what you know from the browser SDK to the server.
* [Best practices][]: Pace frames, manage resources, and troubleshoot common issues.

[`examples` directory]: https://github.com/twilio/twilio-video-node/tree/main/examples

[`twilio` helper library]: https://www.npmjs.com/package/twilio

[`virtual_camera.js`]: https://github.com/twilio/twilio-video-node/blob/main/examples/virtual_camera.js

[Best practices]: /docs/video/node-best-practices

[Create a Twilio account]: https://www.twilio.com/try-twilio

[Differences from the JavaScript SDK]: /docs/video/node-differences-from-javascript-sdk

[Generate an Access Token]: /docs/video/tutorials/user-identity-access-tokens

[i420]: /docs/glossary/i420

[Overview]: /docs/video/node

[SDK repository]: https://github.com/twilio/twilio-video-node/tree/main/examples

[system requirements]: /docs/video/node#system-requirements

[Work with media frames]: /docs/video/node-working-with-media-frames
