import {
StreamCall,
StreamVideo,
StreamVideoClient,
User,
} from "@stream-io/video-react-native-sdk";
import { useEffect, useState } from "react";
const apiKey = "your-api-key";
const userId = "user-id";
const token = "authentication-token";
const callId = "my-call-id";
const user: User = { id: userId };
const client = StreamVideoClient.getOrCreateInstance({ apiKey, user, token });
const call = client.call("default", callId);
call.join({ create: true });
export default function App() {
return (
<StreamVideo client={client}>
<StreamCall call={call}>{/* Your UI */}</StreamCall>
</StreamVideo>
);
}Quickstart
This guide covers the basics of making your first call using Stream Video. If you haven't already, start with the introduction and installation (Native CLI or Expo) steps first.
Best Practices
- Use singleton pattern - Always use
StreamVideoClient.getOrCreateInstance()instead of creating new client instances - Clean up resources - Call
call.leave()when leaving a call to release allocated resources - Test on real devices - iOS simulators don't support audio/video recording; Android emulators have limited support
- Handle call lifecycle - Use
useEffectcleanup functions to properly dispose of call instances - Request permissions just-in-time - Ask for camera and microphone access right before first use
Client setup & Calls
Create an instance of StreamVideoClient that will establish a WebSocket connection by connecting a user. Next, you create a call object and join the call. We'll specify create: true to create the call if it doesn't exist.
Use StreamVideoClient.getOrCreateInstance() instead of new StreamVideoClient() to ensure a singleton instance. Multiple client instances can break push notifications and call state management.
When creating a call on the client, the string default is a call type. There are 4 built-in call types and you can also create your own.
The call type controls the permissions and which features are enabled.
The second argument is the call id. Call ids can be reused, meaning it's possible to join a call with the same id multiple times (for example, for recurring meetings). However, for ringing calls, you should always provide a unique call id.
Rendering video
The call's state can be accessed using hooks, all exposed through the top-level useCallStateHooks hook.
Access participant state using hooks like useParticipants. Basic video rendering example:
import {
useCallStateHooks,
CallParticipantsList,
} from "@stream-io/video-react-native-sdk";
function VideoUI() {
const { useParticipants } = useCallStateHooks();
const participants = useParticipants();
return <CallParticipantsList participants={participants} />;
}The participant object contains all essential information to render videos, such as audio/video tracks, user information, audio/video enabled status, etc.
More information about state management can be found in the Call & Participant State guide.
Camera & Microphone
Most video apps show buttons to mute/unmute audio or video. Camera and microphone usage example:
import { Button } from "react-native";
import { useCallStateHooks } from "@stream-io/video-react-sdk";
export const MyVideoButton = () => {
const { useCameraState } = useCallStateHooks();
const { camera, isMute } = useCameraState();
return (
<Button
title={isMute ? "Turn on camera" : "Turn off camera"}
onPress={() => camera.toggle()}
/>
);
};
export const MyMicrophoneButton = () => {
const { useMicrophoneState } = useCallStateHooks();
const { microphone, isMute } = useMicrophoneState();
return (
<Button
title={isMute ? "Turn on microphone" : "Turn off microphone"}
onPress={() => microphone.toggle()}
/>
);
};More information about this topic can be found in the Camera & Microphone guide.
UI Components
Build any type of video/calling experience with these UI options:
- Build your own UI components using the state as shown above.
- Use our library of built-in components.
- Mix & Match between your own and built-in components.
If you're using our built-in components, you can easily customize them through theming and props. For creating your own components, the UI Cookbook section is there to help you get started.
Next steps
For a complete integration, review our Integration Best Practices guide covering lifecycle management, error handling, and device management.