# Quickstart (/en/realtime-media/rtc/get-started-sdk/javascript)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

This page provides a step-by-step guide on how to create a basic real-time app using the Agora RTC SDK. The same steps apply whether you're building voice calling, video calling, interactive live streaming, or broadcast streaming — only a few configuration values change based on your use case.

## Understand the tech

To start a real-time session, implement the following steps in your app:

* **Initialize the engine**: Before calling other APIs, create and initialize an engine instance.

* **Join a channel**: Call methods to create and join a channel.

  * **Join as a host**: A live streaming event has one or more hosts. A host publishes audio and video to the channel and can also subscribe to streams from other hosts.

  * **Join as audience**: Audience members can only subscribe to streams published by hosts.

  <CalloutContainer type="info">
    <CalloutTitle>
      Note
    </CalloutTitle>

    <CalloutDescription>
      For the voice calling and video calling use cases, each user joins as a host.
    </CalloutDescription>
  </CalloutContainer>

* **Send and receive audio and video**: Hosts publish streams to the channel. Audience members subscribe to audio and video streams published by hosts.

* For streaming applications, set the latency level based on your use case:

  * **Interactive live streaming**: Optimized for real-time interaction with ultra-low latency. Use this when hosts and audience need to interact quickly, such as in live Q\&A sessions, interactive classrooms, or auctions.

  * **Broadcast streaming**: Optimized for scalability with slightly higher latency. Use this for large-scale events where one-way broadcasting is sufficient, such as concerts, sports events, or news broadcasts.

![Realtime communication workflow](https://assets-docs.agora.io/images/video-sdk/video-call.svg)

<CalloutContainer type="info">
  <CalloutTitle>
    React SDK and Web SDK relationship
  </CalloutTitle>

  <CalloutDescription>
    The React SDK is built on Web SDK 4.x and includes its APIs. For example, `useLocalMicrophoneTrack` calls the Web SDK `createMicrophoneAudioTrack` method.

    Use the React SDK for basic real-time audio and video features. For advanced or complex scenarios, use the Web SDK. When a feature requires the Web SDK, the React SDK documentation links to the relevant Web SDK API pages.
  </CalloutDescription>
</CalloutContainer>

## Prerequisites

* A camera and a microphone.
* A valid Agora account and project. See [Agora account management](/en/realtime-media/rtc/manage-agora-account) for details.
* A [supported browser](/en/realtime-media/rtc/reference/supported-platforms#mobile-browsers).
* A JavaScript package manager such as [npm](https://www.npmjs.com/package/npm).

## Set up your project

### Create a project

To create a new ReactJS project with the necessary dependencies:

1. Ensure that you have installed [Node.js LTS](https://nodejs.org/en) and `npm`.

2. Open a terminal and execute:

   ```bash
   npm create vite@latest agora-sdk-quickstart -- --template react-ts
   ```

   This creates a new project folder named `agora-sdk-quickstart`. Open the folder in your preferred IDE.

### Install the SDK

Use one of the following methods to install the project dependencies:

<Tabs defaultValue="npm">
  <TabsList>
    <TabsTrigger value="npm">
      npm
    </TabsTrigger>

    <TabsTrigger value="cdn">
      CDN
    </TabsTrigger>
  </TabsList>

  <TabsContent value="npm">
    Navigate to the project folder and run the following command to install the RTC SDK:

    ```bash
    npm i agora-rtc-react
    ```
  </TabsContent>

  <TabsContent value="cdn">
    To integrate React JS dependencies and the Agora SDK using CDN, add the following code to your HTML file:

    ```html
    <!-- Include the React development libraries (must be introduced in this order) -->
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>

    <!-- If the above React libraries have already been integrated through npm, skip them and include only the Agora RTC React SDK -->
    <script src="https://download.agora.io/sdk/release/agora-rtc-react.2.3.0.js"></script>
    ```
  </TabsContent>
</Tabs>

## Implement Realtime Communication

This section guides you through the implementation of basic real-time audio and video interaction in your app.

This guide includes [complete sample code](#complete-sample-code) that demonstrates implementing basic real-time interaction. To understand the core API calls in the sample code, review the following implementation steps.

### Import Agora hooks and components

To use RTC SDK in your component, include the following imports:

```jsx
import {
  LocalUser, // Plays the microphone audio track and the camera video track
  RemoteUser, // Plays the remote user audio and video tracks
  useIsConnected, // Returns whether the SDK is connected to Agora's server
  useJoin, // Automatically join and leave a channel on mount and unmount
  useLocalMicrophoneTrack, // Create a local microphone audio track
  useLocalCameraTrack, // Create a local camera video track
  usePublish, // Publish the local tracks
  useRemoteUsers, // Retrieve the list of remote users
} from "agora-rtc-react";
import AgoraRTC, { AgoraRTCProvider } from "agora-rtc-react";
import { useState } from "react";
```

### Initialize the client

Use the `createClient` method provided by the SDK to create a client object for the `<AgoraRTCProvider />` component. Wrap the `<Basics />` component with `<AgoraRTCProvider />` to enable state management and access operation-related hooks.

Set the channel profile, client role, and audience latency level according to your use case.

| Use case                   | Channel profile | Client role              | Latency level                    |
| -------------------------- | --------------- | ------------------------ | -------------------------------- |
| Voice calling              | `"rtc"`         | —                        | `2`: Ultra low latency (default) |
| Video calling              | `"rtc"`         | —                        | `2`: Ultra low latency (default) |
| Interactive live streaming | `"live"`        | `"host"` or `"audience"` | `2`: Ultra low latency (default) |
| Broadcast streaming        | `"live"`        | `"host"` or `"audience"` | `1`: Low latency                 |

<CalloutContainer type="info">
  <CalloutTitle>
    Note
  </CalloutTitle>

  <CalloutDescription>
    * Only hosts can publish media. Audience members cannot publish until promoted to host.
    * Choose `rtc` mode for calls where every user publishes, typically fewer than 17 participants. Choose `live` mode for larger events with separate hosts and audience.
    * The latency level only applies to the audience role, and affects your [pricing](/en/realtime-media/rtc/reference/pricing#subscription-packages) tier.
  </CalloutDescription>
</CalloutContainer>

The following example shows a live-streaming audience configuration. Adjust the mode, role, and latency values according to your use case.

```jsx
export const RealtimeCommunication = () => {
  // Example: interactive live streaming as an audience member
  const client = AgoraRTC.createClient({ mode: "live", codec: "vp8" });

  client.setClientRole("audience", { level: 2 });

  // For voice or video calling:
  // use mode: "rtc" and do not set a client role

  // For broadcast streaming:
  // client.setClientRole("audience", { level: 1 });

  // To join as a host:
  // client.setClientRole("host");

  return (
    <AgoraRTCProvider client={client}>
      <Basics />
    </AgoraRTCProvider>
  );
};
```

### Join a channel

To join a channel, use the `useJoin` hook. You can specify the following `joinOptions`:

* **App ID**: [`appid`](/en/realtime-media/rtc/manage-agora-account#get-the-app-id) identifies the project you created in Agora Console.

* **Channel name**: The name of the `channel` to join. Clients that pass the same channel name join the same channel. If a channel with the specified name does not exist, it is created when the first user joins.

* **Authentication token**: A `token` is a dynamic key that authenticates a user when the client joins a channel. In a production environment, you obtain a token from a [token server](/en/realtime-media/rtc/build/authenticate-users/deploy-token-server) in your security infrastructure. For the purpose of this guide [Generate a temporary token](/en/realtime-media/rtc/manage-agora-account#generate-temporary-tokens).

* **User ID**: `uid` is a 32-bit signed integer that identifies a user in the channel. You can specify a unique user ID for each user yourself. If you do not set a user ID or set it to `0` when joining a channel, the SDK generates a random number for the user ID and returns the value.

Add the following to `Basics`:

```jsx
const [appId, setAppId] = useState("<-- Insert App ID -->");
const [channel, setChannel] = useState("<-- Insert Channel Name -->");
const [token, setToken] = useState("<-- Insert Token -->");
const [calling, setCalling] = useState(false);

useJoin({appid: appId, channel: channel, token: token ? token : null}, calling);
```

### Create local audio and video tracks

To create local audio and video tracks, use the `useLocalMicrophoneTrack` and `useLocalCameraTrack` hooks. Add the following to `Basics`:

```jsx
const { localMicrophoneTrack } = useLocalMicrophoneTrack(micOn);
const { localCameraTrack } = useLocalCameraTrack(cameraOn);
```

### Publish tracks in the channel

After joining a channel, publish the local audio and video tracks using the `usePublish` hook. Add the following to `Basics`:

```jsx
const [micOn, setMic] = useState(true);
const [cameraOn, setCamera] = useState(true);
const { localMicrophoneTrack } = useLocalMicrophoneTrack(micOn);
const { localCameraTrack } = useLocalCameraTrack(cameraOn);

usePublish([localMicrophoneTrack, localCameraTrack]);
```

### Display the local video

To display the local video, use the `LocalUser` hook, which provides properties to manage local audio and video tracks. Assign the local video track to `videoTrack` and the audio track to `audioTrack`. Use the `micOn` and `cameraOn` parameters to toggle audio and video. Include the following code in the markup of your `Basics` component:

```jsx
<LocalUser
  audioTrack={localMicrophoneTrack}
  cameraOn={cameraOn}
  micOn={micOn}
  videoTrack={localCameraTrack}
  style={{width: '50%', height: 300 }}
>
```

### Display remote video

To manage and display the list of remote users connected to a channel, use the `useRemoteUsers` hook. To show each user's video, pass the user object to the `RemoteUser` component along with the required properties. Follow these steps to implement the logic:

1. **Retrieve the list of remote users**

   Use the `useRemoteUsers` hook to get the current list of remote users:

   ```jsx
   const remoteUsers = useRemoteUsers();
   ```

2. **Render the remoteUser component**

   Loop through the `remoteUsers` list and nest the `RemoteUser` component where you want to display each user's video. Include the following code in the markup of your `Basics` component:

   ```jsx
   {remoteUsers.map((user) => (
     <div key={user.uid}>
       <RemoteUser user={user} style={{ width: '50%', height: 300 }}>
         <samp>{user.uid}</samp>
       </RemoteUser>
     </div>
   ))}
   ```

### Leave the channel

To leave a channel, destroy the component, close the browser window, or refresh the browser tab. The `useJoin` hook automatically handles the destruction of the React component.

### Complete sample code

A complete code sample demonstrating the basic process of real-time interaction is provided for your reference. To use the complete sample, add the following to your `src/App.tsx` file.

<Accordions>
  <Accordion title="Complete sample code for Realtime Communication">
    ```jsx
    import {
      LocalUser,
      RemoteUser,
      useIsConnected,
      useJoin,
      useLocalMicrophoneTrack,
      useLocalCameraTrack,
      usePublish,
      useRemoteUsers,
    } from "agora-rtc-react";
    import { useState } from "react";
    import AgoraRTC, { AgoraRTCProvider } from "agora-rtc-react";

    export const RealtimeCommunication = () => {
      const client = AgoraRTC.createClient({ mode: "live", codec: "vp8" });
      return(
            <AgoraRTCProvider client={client}>
              <Basics />
            </AgoraRTCProvider>
      );
    }

    const Basics = () => {
      const [calling, setCalling] = useState(false);
      const isConnected = useIsConnected(); // Store the user's connection status
      const [appId, setAppId] = useState("<-- Insert App ID -->");
      const [channel, setChannel] = useState("<-- Insert Channel Name -->");
      const [token, setToken] = useState("<-- Insert Token -->");
      const [micOn, setMic] = useState(true);
      const [cameraOn, setCamera] = useState(true);
          
      const { localMicrophoneTrack } = useLocalMicrophoneTrack(micOn);
      const { localCameraTrack } = useLocalCameraTrack(cameraOn);

      useJoin({appid: appId, channel: channel, token: token ? token : null}, calling);
      usePublish([localMicrophoneTrack, localCameraTrack]);

      const remoteUsers = useRemoteUsers();

      return (
        <>
          <div>
            {isConnected ? (
              <div>
                <div>
                  <LocalUser
                    audioTrack={localMicrophoneTrack}
                    cameraOn={cameraOn}
                    playAudio={false} // Plays the local user's audio track. You use this to test your mic before joining a channel.
                    micOn={micOn}
                    videoTrack={localCameraTrack}
                    style={{width: '90%', height: 300 }}
                  >
                    <samp>You</samp>
                  </LocalUser>
                </div>
                {remoteUsers.map((user) => (
                  <div key={user.uid}>
                    <RemoteUser user={user} style={{width: '90%', height: 300 }}>
                      <samp>{user.uid}</samp>
                    </RemoteUser>
                  </div>
                ))}
              </div>
            ) : (
              <div>
                <input
                  onChange={e => setAppId(e.target.value)}
                  placeholder="<Your app ID>"
                  value={appId}
                />
                <input
                  onChange={e => setChannel(e.target.value)}
                  placeholder="<Your channel Name>"
                  value={channel}
                />
                <input
                  onChange={e => setToken(e.target.value)}
                  placeholder="<Your token>"
                  value={token}
                />

                <button
                  disabled={!appId || !channel}
                  onClick={() => setCalling(true)}
                >
                  <span>Join Channel</span>
                </button>
              </div>
            )}
          </div>
          {isConnected && (
            <div style={{padding: "20px"}}>
              <div>
                <button onClick={() => setMic(a => !a)}>
                  {micOn ? "Disable mic" : "Enable mic" }
                </button>
                <button onClick={() => setCamera(a => !a)}>
                  {cameraOn ? "Disable camera " : "Enable camera" }
                </button>
                <button
                  onClick={() => setCalling(a => !a)}
                  >
                  {calling ? "End calling" : "Start calling"}
                </button>
              </div>
            </div>
          )}
        </>
      );
    };
          
    export default RealtimeCommunication;
    ```
  </Accordion>
</Accordions>

## Test the sample code

Use [CodeSandbox](https://codesandbox.io/), to swiftly run the complete demo code and experience the RTC SDK functionality in just a few simple steps.

<iframe src="https://codesandbox.io/embed/github/AgoraIO/quickstart-examples/tree/EN-docs/rtc/react-quickstart?codemirror=1&fontsize=14&hidenavigation=1&theme=dark&hidedevtools=1&module=/src/index.js" style="{ width: '100%', height: '500px', border: '0', borderRadius: '4px', overflow: 'hidden' }" title="agora-rtc-react-quickstart" allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts" />

<p />

To run the demo code in `CodeSandbox`:

1. Fill in the app ID and the temporary token you obtained from Agora Console. Use the same channel name you used to generate the token.
2. Click the **Join Channel** button. You see yourself in the video.
3. Ask a friend to open the same demo link in their browser and join the channel using the same app ID, channel name, and temporary token as yours. After successfully joining the channel, you can see and hear each other.
4. Click the microphone and camera buttons at the bottom to switch on, or turn off the corresponding devices.
5. Click the hang-up button to end the call.

To experiment and learn more, modify the code directly in the editor on the left, and preview the runtime effect on the right.

<CalloutContainer type="info">
  <CalloutTitle>
    Note
  </CalloutTitle>

  <CalloutDescription>
    If `CodeSandbox` access is slow, try adjusting your network configuration.
  </CalloutDescription>
</CalloutContainer>

## Reference

This section contains content that completes the information on this page, or points you to documentation that explains other aspects of this product.

* If a firewall is deployed in your network environment, refer to [Connect with Cloud Proxy](/en/realtime-media/rtc/build/manage-connection-and-quality/cloud-proxy) to use Agora services normally.

### Next steps

After implementing the quickstart sample, read the following documents to learn more:

* To ensure communication security in a test or production environment, best practice is to obtain and use a token from an authentication server. For details, see [Secure authentication with tokens](/en/realtime-media/rtc/build/authenticate-users/authentication-workflow).

### Sample project

Agora provides an open source [sample project on GitHub](https://github.com/AgoraIO-Extensions/agora-rtc-react) for your reference. The project demonstrates the use of each component and hook provided by the React SDK, as well as some advanced functions.

### API reference

* [`LocalUser`](https://api-ref.agora.io/en/video-sdk/reactjs/2.x/functions/LocalUser.html)
* [`RemoteUser`](https://api-ref.agora.io/en/video-sdk/reactjs/2.x/functions/RemoteUser.html)
* [`useIsConnected()`](https://api-ref.agora.io/en/video-sdk/reactjs/2.x/functions/useIsConnected.html)
* [`useJoin()`](https://api-ref.agora.io/en/video-sdk/reactjs/2.x/functions/useJoin.html)
* [`useLocalMicrophoneTrack()`](https://api-ref.agora.io/en/video-sdk/reactjs/2.x/functions/useLocalMicrophoneTrack.html)
* [`usePublish()`](https://api-ref.agora.io/en/video-sdk/reactjs/2.x/functions/usePublish.html)
* [`useRemoteUsers()`](https://api-ref.agora.io/en/video-sdk/reactjs/2.x/functions/useRemoteUsers.html)

### See also

* [SDK error codes](/en/realtime-media/rtc/reference/error-codes)

    
  
      
  
      
  
      
  
