Screen Sharing for Expo React Native (iOS)
This guide walks you through integrating screen sharing functionality for iOS in your Expo React Native application using Video SDK.
note
This page uses the following asynchronous methods. Refer to their API reference for the errors each Promise may reject with, and handle these rejections appropriately based on your use case.
Install the plugin:
- NPM
- YARN
npm install @videosdk.live/expo-ios-screen-share
yarn add @videosdk.live/expo-ios-screen-share
Usage
Update your app.json to include the plugin along with your Apple Developer teamId and an optional extensionName:
{
"plugins": [
[
"@videosdk.live/expo-ios-screen-share",
{
"appleTeamId": "YOUR_APPLE_TEAM_ID", // example: "EHV7XZLAHA"
"extensionName": "YOUR_BROADCAST_EXTENSION_NAME",
}
],
]
}
info
If no extensionName is provided, the default value broadcast will be used.
What This Plugin Does
- Adds a Broadcast Upload Extension target.
- Configures App Group, Entitlements, and Info.plist entries.
- Automatically links the broadcast extension with your main app target.
- Minimizes manual native code configuration required for ReplayKit.
- Provides a native bridge (VideosdkRPK.swift) for broadcasting control.
VideosdkRPK.js file
Create a JS bridge to interface with the native broadcast extension:
import { NativeModules, NativeEventEmitter, Platform } from 'react-native';
const { VideosdkRPK } = NativeModules;
if (!VideosdkRPK) {
console.warn('⚠️ Native Module VideosdkRPK is not loaded');
}
const emitter = Platform.OS === 'ios' && VideosdkRPK ? new NativeEventEmitter(VideosdkRPK) : null;
const VideosdkBridge = {
startBroadcast: Platform.OS === 'ios' ? () => VideosdkRPK?.startBroadcast() : () => {},
addListener: (callback) => {
if (!emitter) return { remove: () => {} };
return emitter.addListener('onScreenShare', callback);
},
removeListener: (subscription) => {
subscription?.remove?.();
},
};
export default VideosdkBridge;
Implementing Screen Share Controls
import VideosdkRPK from "./VideosdkRPK";
function ControlsContainer() {
const {toggleScreenShare} = useMeeting({});
useEffect(() => {
const subscription = VideosdkRPK.addListener((event) => {
if (event === "START_BROADCAST") {
try {
await toggleScreenShare();
} catch (err) {
console.error("toggleScreenShare failed:", err);
}
} else if (event === "STOP_BROADCAST") {
try {
await toggleScreenShare();
} catch (err) {
console.error("toggleScreenShare failed:", err);
}
}
});
return () => {
VideosdkRPK.removeListener(subscription);
};
}, []);
return (
<View
style={{
padding: 24,
flexDirection: "row",
justifyContent: "space-between",
}}
>
<Button
onPress={async () => {
VideosdkRPK.startBroadcast();
}}
buttonText={"Screen Share"}
backgroundColor={"#1178F8"}
/>
</View>
);
}
Got a Question? Ask us on discord

