# Get started
The React Native SDK is a wrapper for the Video SDK for Android and the Video SDK for iOS. Your React Native application communicates with the native Zoom Video SDK over the React Native bridge primarily through the Zoom Video SDK instance.
## Prerequisites:
- [Environment setup](https://reactnative.dev/docs/environment-setup) for React Native
- Node (LTS) & Yarn
- A Zoom [Video SDK Account](/docs/video-sdk/get-credentials/)
## Add Video SDK into your project
For an easy setup, we recommend using [Expo](https://expo.dev/). You can also use the [React Native CLI](https://reactnative.dev/docs/environment-setup#creating-a-new-application). We also recommend that you use **yarn** rather than **npm** for the installation.
### Add Video SDK into your Expo project
Follow these steps to integrate Video SDK for React Native into your [Expo project](https://docs.expo.dev/tutorial/create-your-first-app/).
1. [Create an Expo project](https://docs.expo.dev/get-started/installation/#get-started). You can use the following command:
```shell
yarn create expo zoom-video-sdk --template # select Blank (Typescript)
```
You can skip this step if you have an existing project.
2. Install the Zoom Video SDK with `yarn add @zoom/react-native-videosdk`. For iOS run `npx pod-install` to install the pods.
3. Add the [camera and microphone permissions](https://docs.expo.dev/guides/permissions/) to your `app.json`.
```json
{
"expo": {
"ios": {
"infoPlist": {
"NSCameraUsageDescription": "This app uses the camera to share your video.",
"NSMicrophoneUsageDescription": "This app uses the microphone to share your audio.",
"NSBluetoothPeripheralUsageDescription": "Required for Bluetooth audio devices",
"NSPhotoLibraryUsageDescription": "Required to use screen share feature"
}
},
"android": {
"permissions": ["CAMERA", "RECORD_AUDIO"]
}
}
}
```
See the list of required and optional permissions for iOS apps in the [Video SDK for iOS: permissions documentation](/docs/video-sdk/ios/integrate/#add-required-project-permissions).
For Android, add the camera and microphone permissions at a minimum, and bluetooth and photo library permissions to support other features. See the full list of required permissions for Android apps in the [Video SDK for Android: permissions documentation](/docs/video-sdk/android/integrate/#add-permissions).
4. Execute `npx expo prebuild` to populate the `ios` and `android` directories.
5. Execute `npx expo run:android` or `npx expo run:ios` to create and install a development build on your device. Please make sure you have a physical device connected to your computer for testing.
### Add Video SDK into your project using the [React Native CLI](https://reactnative.dev/docs/environment-setup#react-native-command-line-interface)
1. Create a new project using the [React Native CLI](https://reactnative.dev/docs/environment-setup#creating-a-new-application). You can use the following command:
```shell
npx react-native@latest init zoomRNCli --template react-native-template-typescript
```
You can skip this step if you have an existing project.
2. Install the Zoom Video SDK with `yarn add @zoom/react-native-videosdk`.
For iOS run `npx pod-install` to install the pods.
**Android**
The SDK requires camera and microphone permissions at a minimum, and bluetooth and photo library permissions to support other features. See the full list of required permissions for Android apps in the [Video SDK for Android: permissions documentation](/docs/video-sdk/android/integrate/#add-permissions).
**iOS**
If you are building on iOS arm64 simulators, add this section into the `ios/Podfile`.
```ruby
post_install do |installer|
# https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
react_native_post_install(
installer,
config[:reactNativePath],
:mac_catalyst_enabled => false
)
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'NO'
config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', '_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION']
end
end
end
```
The SDK requires at least the camera and microphone permissions. See the list of required and optional permissions for iOS apps in the [Video SDK for iOS: permissions documentation](/docs/video-sdk/ios/integrate/#add-required-project-permissions). See the Apple developer documentation, [Provide a purpose string](https://developer.apple.com/documentation/uikit/protecting_the_user_s_privacy/requesting_access_to_protected_resources/#3037322), for guidance on handling iOS permissions with React Native. You must add `NSCameraUsageDescription` and `NSMicrophoneUsageDescription`. You can also set `Validate Workspace` in the project > build settings to "Yes" to help debug any potential errors.
3. To create and install a development build on your device you can run execute:
- For Android run `npm run android`.
- For iOS run `npm run ios`.
Make sure you have a physical device connected to your computer for testing.
> The iOS simulator will not be able to access the camera, you'll see an empty video view. Use a physical device to test the video functionality.
## Import SDK
Import the `ZoomVideoSdkProvider` from the SDK. This context wrapper is required for the components within the application that make use of the React Native Zoom Video SDK. Wrap your app with this provider and pass in configuration properties as shown in the following example.
```tsx
import { ZoomVideoSdkProvider } from "@zoom/react-native-videosdk";
;
```
Your application requires the values passed into the `config` property to initialize the native SDK wrapped by this React Native SDK. The SDK will use these values throughout your application.
### Table of `ZoomVideoSdkProvider` `config` properties
The table below lists the available `config` properties.
| Property | Description |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `appGroupId` | This is a unique value for iOS that ties your app's `ScreenShare` target and your application's main target.See [Set up App Groups](/docs/video-sdk/ios/share#6-set-up-app-groups) in the **Zoom Marketplace iOS Video SDK screen sharing** for details on how to set up this reverse domain order value.You do not need to set this value for the Android platform. If you don't plan to implement screen sharing in video sessions, this value is optional. |
| `domain` | Set this value to `zoom.us` as instructed in the Zoom Marketplace Video SDK guides to [Initialize the iOS SDK](/docs/video-sdk/ios/integrate/#initialize-the-sdk) and [Initialize the Android SDK](/docs/video-sdk/android/integrate/#initialize-the-sdk). |
| `enableLog` | Set to `true` to enable debugging if you wish to do so.When you are getting started, we recommend setting this property to `true`; otherwise, explicitly set it to `false` so other developers will know why logging is disabled. |
You can access the SDK instance using the `useZoom` hook in the components wrapped within the provider.
```javascript
import { useZoom } from '@zoom/react-native-videosdk';
const MyApp = () => {
const zoom = useZoom();
// ...
```
Create the following pieces of react state.
1. `users` to keep track of all the users in the call.
2. `isInSession` to track if the user is in an active session.
3. A `listeners` ref to store event subscriptions.
```javascript
const Call = () => {
const zoom = useZoom();
const [users, setUsersInSession] = useState([]);
const [isInSession, setIsInSession] = useState(false);
const listeners = useRef([]);
}
```
## Join a session
To join a session, you'll authenticate, then use event listeners to keep track of users and states.
### Authenticate
You'll need a Video SDK key and secret to generate a JSON Web Token (JWT) for your application to authenticate a session with the Video SDK. **You should not store these credentials in the application itself.** See [Video SDK Authentication](/docs/video-sdk/auth/) for details.
```typescript
const join = async () => {
const token = "";
};
```
### Event Listeners
The Video SDK triggers events for various actions such as when a user joins or leaves a session and when their status changes, such as their video status. Listen to these events using the `addListener` method. Use these listeners to keep track of all the users in the session as they join and leave.
#### `onSessionJoin`
The `onSessionJoin` event is fired when the user joins a session. Use this to update the `users` state and set the `isInSession` state to `true`. Append the returned subscription `sessionJoin` to the listeners ref to have a reference for cleaning it up later.
```typescript
const sessionJoin = zoom.addListener(EventType.onSessionJoin, async () => {
const mySelf = new ZoomVideoSdkUser(await zoom.session.getMySelf());
const remoteUsers = await zoom.session.getRemoteUsers();
setUsersInSession([mySelf, ...remoteUsers]);
setIsInSession(true);
});
listeners.current.push(sessionJoin);
```
#### `onUserJoin` and `onUserLeave`
The `onUserJoin` and `onUserLeave` event is fired when a new remote user joins or leaves the session. Use this to update the `users` state when people join or leave the session.
```typescript
const userJoin = zoom.addListener(EventType.onUserJoin, async (event) => {
const { remoteUsers } = event;
const mySelf = await zoom.session.getMySelf();
const remote = remoteUsers.map((user) => new ZoomVideoSdkUser(user));
setUsersInSession([mySelf, ...remote]);
});
listeners.current.push(userJoin);
const userLeave = zoom.addListener(EventType.onUserLeave, async (event) => {
const { remoteUsers } = event;
const mySelf = await zoom.session.getMySelf();
const remote = remoteUsers.map((user) => new ZoomVideoSdkUser(user));
setUsersInSession([mySelf, ...remote]);
});
listeners.current.push(userLeave);
```
#### `onSessionLeave`
The `onSessionLeave` event is fired when the local user leaves a session. The callback provides the reason why the session ended.
```typescript
const sessionLeave = zoom.addListener(
EventType.onSessionLeave,
(reason: any) => {
console.log("Leave reason: " + JSON.stringify(reason));
},
);
```
### Join the session
The `joinSession` method on the zoom `object` creates or joins a Video SDK session. You must pass in the session details along with `audioOptions` and `videoOptions`. **Make sure the generated JWT matches these values.**
```typescript
await zoom
.joinSession({
sessionName: "DemoSession",
sessionPassword: "",
userName: "DemoUser",
sessionIdleTimeoutMins: 10,
token: token,
audioOptions: {
connect: true,
mute: true,
autoAdjustSpeakerVolume: false,
},
videoOptions: { localVideoOn: true },
})
.catch((e) => {
console.log(e);
});
```
#### `isInSession`
To leave a session, call the `leaveSession` method on the `zoom` object. You can optionally pass in `true` as the function parameter to end the session for all users. On leaving the session update the `isInSession` state and remove all the listener subscriptions.
```typescript
const leaveSession = () => {
zoom.leaveSession(false);
setIsInSession(false);
listeners.current.forEach((listener) => listener.remove());
listeners.current = [];
};
```
## Render the videos
The component renders conditionally based on the `isInSession` state. If the user is in an active session, render the videos for each user by mapping over the users state and passing in their `userId` to the `ZoomView` component. Render a `Button` to leave the session.
```typescript
return isInSession ? (
{users.map((user) => (
))}
) : (
// If the user is not in an active session, render a button to join the session.
);
};
```
Once you refresh the application bundle, you should see a button to join the session on your screen. You can click this button to join the `demo` session and view your video on screen. You can join this session from a different device to see and hear the other users.
## Sign developer cert (iOS only)
For iOS integrations, sign your developer certificate to your project. Follow these steps in Xcode:
1. In Xcode, go to the project configuration page.
2. In the **Signing & Capabilities** pane in the project editor, select **Automatically managed signing**. Xcode creates the development signing assets for you.
3. Set up a unique bundle identifier and use your own team to sign your developer certificate.
See the [Apple developer documentation: Code Signing Tasks](https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html) guide for details.
_You must also follow Apple's requirement to provide [a privacy manifest and signatures](https://developer.apple.com/support/third-party-SDK-requirements/) when creating an iOS app._
## Learn more and add features
For more examples, see the blog post: [Build a React Native video conferencing app with the Zoom Video SDK & Expo](/blog/build-a-react-native-video-conferencing-app-with-the-zoom-video-sdk-and-expo/) and the Z**oom Video SDK React Native Demo** app on GitHub.
- [Zoom Video SDK React Native Demo](https://github.com/zoom/VideoSDK-ReactNative-Quickstart)
See the documentation in the **Add features** section to add more features such as screen sharing, chat, cloud recording, and live transcription and translation.