@bbb-mobile/bigbluebutton-mobile-sdk
v0.6.0
Published
BigBlueButton meeting SDK for React Native with macOS and Windows support and recording playback: Android, iOS and macOS run the native meeting client (LiveKit WebRTC), Windows renders the html5 client in WebView2 through the package's own react-native-wi
Maintainers
Readme
@bbb-mobile/bigbluebutton-mobile-sdk
BigBlueButton meeting SDK for React Native, on Android, iOS, macOS and Windows. Your app renders
one component with a join URL; the meeting runs full-screen inside your app and calls back, with
the leave reason, when the user leaves or the meeting ends. A second component plays a
BigBlueButton recording from its playback URL (see "Recording playback"). On Android and iOS the meeting client
runs inside your app's own React Native runtime: it ships as TypeScript and JavaScript source that
Metro bundles like the rest of your app, with no Metro configuration to add, and four Expo native
modules come with it (@bbb-mobile/pip, @bbb-mobile/downloads, @bbb-mobile/sdk-host,
@bbb-mobile/video-effects); npm installs them. On macOS (react-native-macos) and Windows
(react-native-windows) the same native client runs without those Expo modules; a Windows host
links @bbb-mobile/windows-host, the package's WebRTC and host services for react-native-windows,
and applies its Metro helper (see "macOS and Windows" below). Apps without React Native
use the native Android and iOS SDKs from the
SDK repository, or
bbb_meeting_sdk in Flutter.
Developed and maintained by BiggerBlueButton.
Requires React Native 0.86 (0.86.3 or later) with the Expo modules runtime (Expo SDK 57) on
Android and iOS; built and tested with React Native 0.86.3 on Android and iOS. On macOS it needs
react-native-macos (0.83 or 0.81.9, each with the shipped patch for its line, both verified) and
the native libraries listed below; on Windows react-native-windows 0.83 or later (new
architecture), the same libraries, @bbb-mobile/windows-host linked into the app's solution
(the Visual Studio toolchain react-native-windows asks for; the first build downloads the pinned
libwebrtc), and the WebView2 runtime for the web renderer and the recording player
(@bbb-mobile/meeting-webview brings its own WebView2 host module; react-native-webview's Windows
project is old-architecture only and stays off).
Install
npm install --save-exact [email protected] # your app's exact react version (19.2.3 in a new React Native 0.86.3 app)
npm install @bbb-mobile/bigbluebutton-mobile-sdkreact-dom goes in first, at exactly the app's react version. The meeting's LiveKit components
list it as a peer, and without it npm picks the newest react-dom, which needs a newer react than
React Native pins, so the install stops with ERESOLVE. npm then installs the four native modules and
the package's peer dependencies, the native libraries the meeting uses (LiveKit, Expo, Reanimated,
Gesture Handler, SVG, WebView, MMKV and others), and autolinking links them. Three of those peers
are deliberate: @livekit/react-native ~3.0.0 and @livekit/react-native-webrtc ~144.2.0 are the
lines the shipped patches are for (LiveKit 3.1 moved to the fork's 150 line, which a caret range
let npm pick), and expo-asset ~57.0.20 is named at all so that npm installs Expo SDK 57's copy
next to expo 57 instead of hoisting Expo SDK 58's, whose expo/internal/bundle-origin import
broke the iOS and Android bundle until 0.3.1. npm also warns
"ERESOLVE overriding peer dependency" because bigbluebutton-html-plugin-sdk asks for React 18;
that warning is expected and the install succeeds (npm ls lists the same two entries as
invalid and exits 1 for that reason alone; nothing is missing). Then the JavaScript and host-app settings below,
once per app.
Usage
import { BigBlueButtonMeeting, configureBigBlueButtonMeeting } from '@bbb-mobile/bigbluebutton-mobile-sdk';
configureBigBlueButtonMeeting({ clientType: 'NATIVE_MOBILE', appVersion: '1.0.0' }); // once, at startup
function MeetingScreen({ joinUrl, onDone }) {
return (
<BigBlueButtonMeeting
joinUrl={joinUrl}
meetingName="Weekly"
onJoined={() => {}}
onLeave={(info) => onDone(info)} // info.reason: left | ended | error | unsupported; info.detail (optional): a code, or an error message
openLogoutUrl={false} // stay in the app when the meeting ends
/>
);
}Render the component full-screen and unmount it in onLeave. One meeting runs at a time, and the
component reads its options when it mounts, so another meeting needs a new mount. Other props:
- the join options the native SDKs also take:
theme,pictureInPicture,screensharePresenter,embedMode,largeScreenLayout,devLogging,videoEffects; leaveSignal, to make the user leave from the app's side;gestureRoot,falsewhen the app already renders aGestureHandlerRootView;afterLeave, rendered once the meeting is over;renderer:auto(default; the native client where it can run, which on Windows means the app links@bbb-mobile/windows-host, the WebView otherwise),web(the html5 client in a WebView on any platform) ornative;webViewPropspasses extra props to the WebView of the web renderer.getMeetingRenderer()returns the renderer the platform uses by default.
configureBigBlueButtonMeeting acts on the whole app. It installs the meeting client's global shims
(window, document, navigator.mediaDevices, …), and it sets the app's audio mode once through
expo-audio: plays in silent mode, recording allowed, mixes with other audio, keeps playing in the
background. It also takes registerWebRtcGlobals. The TypeScript definitions ship with the package.
Video effects
Background blur and scenes, colour filters, AR effects (face props, particles), touch-up and low
light for the user's own camera, applied on the device before the video is encoded, so every other
participant sees the result. The meeting UI owns them: the camera sheet shows the picker under the
live preview and the own camera tile's long-press menu opens "Video effects" while the camera is
on; screen share is never processed. They are on by default; videoEffects={false} hides the
picker and never runs a frame processor. The native side is
@bbb-mobile/video-effects. On Android
it uses OpenGL and ML Kit selfie segmentation and face detection: Gradle fetches Google's ML Kit
libraries from Google's Maven repository, they add about 20 MB of native code per ABI, and their
models are bundled, so nothing is downloaded at runtime. ML Kit sends device and app information,
per-installation identifiers and performance metrics to Google
(ML Kit data disclosure); declare them
in the app's Google Play Data safety form. On iOS it uses Vision and Core Image.
External video in the meeting
"Play video from link" (the presenter's Media sheet) plays YouTube, Vimeo and media-file links in
the meeting on every server since 0.4.0. The stage draws a seek bar under the video (position and
duration) and gives the presenter a play / pause button in the toolbar next to the volume and
stop-sharing buttons; those drive everyone's player through the meeting's shared state, so
viewers follow play, pause and seeks (their own bar is read-only), and the volume applies locally. Other providers need the html5 "embed mode" page
(/html5client/embed) that only servers built from the project's html5 have; without it the
stage says the video cannot be played here.
Recording playback
import { BigBlueButtonPlayback } from '@bbb-mobile/bigbluebutton-mobile-sdk';
function RecordingScreen({ playbackUrl, startAt, onDone }) {
return (
<BigBlueButtonPlayback
playbackUrl={playbackUrl} // https://<server>/playback/presentation/2.3/<recordId>
recordingName="Weekly, 12 May"
startAt={startAt} // seconds, optional
onReady={() => {}} // the recording is on screen
onProgress={(seconds) => {}} // about once per second while it plays: keep it to resume later
onEnded={() => {}} // the recording reached its end
onClose={(info) => onDone(info)} // info.reason: closed | error; info.detail: host_close or an error code
closeSignal={subscribeClose} // (listener) => unsubscribe; listener() closes from the app's side
/>
);
}A recording is published in playback formats, each with a URL the server's getRecordings API
returns; playbackUrl takes any of them: the presentation player
(https://<server>/playback/presentation/2.3/<recordId>: slides, whiteboard, webcams, screen
share, chat, polls, notes, captions), the video format (…/playback/video/<recordId>/), or any
other https URL a portal hands out. It also plays video links: YouTube (youtu.be, watch?v=,
shorts, live), Vimeo, and direct media files (mp4, webm, mov, m3u8, mp3, …), in the site's
embedded player or a plain video element, with the same callbacks (startAt included; a YouTube
video that may not be embedded ends with player_youtube_150; embedOrigin, default
https://bigbluebutton.org, is the referrer the embedded player sees: pass the app's website if
its videos are restricted to that domain). The server's own player renders in the platform WebView
(WKWebView on iOS and macOS, the system WebView on Android, WebView2 on Windows) on every platform
the same way: no WebRTC, no Expo module and none of the meeting's shims are involved, so a screen
that only plays recordings is as light as a WebView. The player has no close button of its own:
draw one (a bar above the component, the Android back key) and call the closeSignal listener,
which ends with onClose({ reason: 'closed', detail: 'host_close' }), or unmount the component.
Failures end with onClose({ reason: 'error' }) and a detail: player_404 (the player's own
screen: no such recording, or not published), http_404 and the like (the page itself),
load_timeout (nothing appeared in loadTimeoutMs, default 60 s), network: …, invalid_url,
webview_terminated. Links inside the recording open in the system browser and the player stays.
theme, devLogging, clientType / appVersion (the user agent), renderLoading,
afterClose, webViewProps and style work as for the meeting. On iOS the recording keeps
playing with the silent switch on and, with UIBackgroundModes: audio in the app (the meeting
needs it too), in the background. The component is
@bbb-mobile/meeting-webview's,
whose page lists every close code.
macOS and Windows
- macOS (react-native-macos): the native
meeting client, the same UI and LiveKit WebRTC stack as on Android and iOS. The package's macOS
entry uses host adapter variants that need no Expo native module (most Expo modules have no
macOS podspec): React Native core and the React Native libraries listed below (LiveKit,
Reanimated, Gesture Handler, MMKV, SVG, Safe Area Context, WebView), nothing from Expo.
getMeetingRenderer()isnative. - Windows (react-native-windows 0.83+,
new architecture): the native meeting client as well, since 0.5.0, through
@bbb-mobile/windows-host, a C++ library the host app links: WebRTC for react-native-windows (the native side of@livekit/react-native-webrtcon a prebuilt libwebrtc the build downloads once, so the library's JavaScript and LiveKit run unchanged), LiveKit's audio session module and the host services of the client's Windows adapter variants (storage, file dialogs, keep-awake, the clipboard, the icon font). react-native-reanimated, react-native-worklets, react-native-gesture-handler, @gorhom/bottom-sheet and react-native-safe-area-context have no react-native-windows build; the package ships JavaScript stand-ins for them and a Metro helper,withBigBlueButtonWindows(@bbb-mobile/bigbluebutton-mobile-sdk/metro), that resolves those five names to the stand-ins when bundling forwindows.getMeetingRenderer()isnativewith the host module linked andwebwithout it: the server's html5 client in WebView2 through@bbb-mobile/meeting-webview, which brings its own WebView2 host module (react-native-webview's Windows project is old-architecture only and is not used). Not on Windows in this release: end-to-end encryption, the SDK's video effects, picture in picture; screen sharing captures the primary screen.
Install without the mobile peer dependencies (they name the native stack for React Native 0.86, ahead of react-native-macos, whose newest line is 0.83; react-native-windows is at 0.83 or later), then the libraries the platform needs:
npm install --legacy-peer-deps @bbb-mobile/bigbluebutton-mobile-sdk
# macOS, the native client's libraries at the versions that go with React Native 0.83.
# react and react-dom at 19.2.3: the SDK's react-dom peer is ~19.2.3, and a stock React Native 0.83
# app ships react 19.2.0, so bump react too (the SDK's desktop sample does).
npm install --legacy-peer-deps @livekit/[email protected] @livekit/[email protected] \
@livekit/components-react @livekit/components-core livekit-client [email protected] [email protected] \
[email protected] [email protected] react-native-gesture-handler@~2.30.0 \
react-native-safe-area-context@~5.6.2 [email protected] [email protected] [email protected] \
[email protected] react-native-get-random-values @gorhom/bottom-sheet react-native-toast-message react-native-url-polyfill
# Windows: the same libraries as macOS (react-native-mmkv and react-native-nitro-modules are not
# used there; the rest is bundled, or runs as a Babel plugin), then link the SDK's two Windows
# projects (@bbb-mobile/windows-host, @bbb-mobile/meeting-webview) and react-native-svg's into the
# solution (run-windows does it too) and build:
npx react-native autolink-windows- macOS: three patches through patch-package - the two LiveKit ones at the top of
node_modules/@bbb-mobile/bigbluebutton-mobile-sdk/patches/and one from itsreact-native-macos/subfolder. The two LiveKit ones carry macOS hunks (the module patch makeslivekit-react-nativebuild for macOS and keeps a remote camera playing while another app has focus, the WebRTC fork patch guards the fork's iOS-only picture-in-picture, audio-session and capture code and renders through the macOS Metal view; iOS is unchanged), andreact-native-macos+<version>.patchadds what the fork is missing: a Fabric<Modal>host for macOS (without it the first dialog the meeting opens throwsException in HostFunctionand takes the client down), a nil-tag guard in the key handler, and a non-finite view transform applied as identity (a NaN transform, re-applied on every display pass, pinned the main thread and froze the window). The 0.81.9 copy also makes the display link's frame clock fall back to the host clock while the link is stopped (it read 0 there, so every UI-thread frame measured 10 ms, Reanimated animations never advanced and the joined meeting was never drawn; 0.83 is not affected).patches/react-native-macos/holds a copy for react-native-macos 0.83.0 and one for 0.81.9: copy only the one that matches your fork, flat into the app'spatches/next to the two LiveKit files (not in a subfolder: patch-package reads subfolders and takes the folder for a scoped package name), leave the other copy out (it fails to apply, and patch-package exits 1), and leavereact-native-view-shot's patch out too, that library is not installed on macOS. Then the samebabel.config.jsplugins and first import as on mobile;cd macos && pod install(autolinking links the pods whose podspec supports macOS and skips the iOS-only ones);NSCameraUsageDescriptionandNSMicrophoneUsageDescriptionin Info.plist, the camera and audio-input entitlements; the SDK's icon fontpackages/bbb-ui-native/assets/fonts/bbb-icons.ttfadded to the app's Copy Bundle Resources withATSApplicationFontsPath=.in Info.plist. A sandboxed app also needscom.apple.security.network.server: with onlynetwork.clientthe meeting reaches the server and joins, but no WebRTC connection is ever established (the client retries "could not establish pc connection" forever). The app delegate must callLivekitReactNative.setup()(from thelivekit_react_nativemodule) before the React host is created: it installs LiveKit's simulcast video encoder factory, and without it the default VP8 encoder refuses the meeting's screen-share layers, so nothing is encoded and a share is dropped after ten seconds as never acknowledged. react-native-svg must be 15.15.5 or newer: 15.15.3 draws nothing at all under the new architecture on macOS - no slide, no annotation, no icon that is an SVG. For the presentation upload, add the package'smacos/BbbMacFilePicker.swiftand.mto the app target (anNSOpenPanel; macOS has no Expo document or image picker and no published React Native one supports it). Without the module the upload rows stay inert. The integration guide spells it out, and its sample has the Podfile, Info.plist and entitlements. - Windows:
npx react-native autolink-windowsafter the install (run-windowsruns it too) linksnode_modules/@bbb-mobile/windows-host/windows/BbbWindowsHost(the native client's host; its first build downloads the pinned libwebrtc archive for x64 or ARM64),node_modules/@bbb-mobile/meeting-webview/windows/BbbMeetingWebView(the WebView2 host, a C++ TurboModule) and react-native-svg'sRNSVGinto the app's solution; rebuild the app. An app that has react-native-webview installed for its other platforms turns its Windows project off ('react-native-webview': { platforms: { windows: null } }inreact-native.config.js; the project is old-architecture only, the library's JavaScript is still bundled). Inmetro.config.js, wrap the config withwithBigBlueButtonWindowsfrom@bbb-mobile/bigbluebutton-mobile-sdk/metro. The two LiveKit patches apply on Windows as well (the module patch's JavaScript hunks); leave the react-native-macos and react-native-svg ones out. The samebabel.config.jsplugins and first import as on mobile. The WebView2 runtime (part of Windows 11; the Evergreen bootstrapper installs it on Windows 10) for the web renderer and the recording player; that host draws the WebView in a window owned by the app's main window, over the component's rectangle, so the app's own React Native content cannot be drawn over it (lay bars out next to it, as the sample does), it grants the camera and microphone to the page, and screen sharing goes through WebView2's picker. The native client captures through libwebrtc's device modules: no runtime prompt, the OS privacy settings decide.
On macOS, screen sharing captures the main display with ScreenCaptureKit (macOS 12.3+; the first
share asks for the Screen Recording permission, which macOS applies to the next launch of the
app), and the presentation upload picks files through the module above. Not available in this
release: picture in picture, the SDK's video effects, alert sounds, sharing a file out of the
meeting and the slide snapshot, microphone and audio output selection (the system defaults are
used); video renders in aspect-fit only. On the desktop (macOS and Windows) the meeting controls
stay a bottom bar in every window shape; they hide after a few idle seconds and a click on the
stage hides them or brings them back (with the whiteboard's tools and the presenter's slide
toolbar). On Windows the meeting uses the system's default microphone and speakers and follows
them when they change (a headset plugged in). Messages, Participants, Notes, Polls, Breakouts, Settings and the other
panels open as a centred popup over the dimmed meeting (at most 560 x 760 points; a click outside
closes it) instead of covering the window, and the meeting keeps its layout and controls under it
(also on tablets and other large screens). The rest of the
meeting is the native client's. On Windows the native client has the same limits (no picture in
picture, video effects or alert sounds, no sharing out and no slide snapshot, the system default
microphone and audio output; frame encryption is rejected), screen sharing captures the primary
screen, and the presentation upload, the poll import and the downloads go through the Windows
file dialogs of the host module. With the WebView
renderer (renderer="web" on any platform, and a Windows app without the host module): the meeting UI is the html5 client's;
theme only colours the loading screen; pictureInPicture, screensharePresenter, embedMode,
largeScreenLayout and videoEffects are accepted and ignored (the html5 client has its own
virtual backgrounds); clientType and appVersion go into the WebView's user agent. The leave reason
comes from the client's own screens and redirects: left when the user leaves (detail
user_logged_out_reason) or the app asked for it (host_leave), ended with the client's ended
code (ENDED_FROM_API, user_requested_eject_reason, 410, …), error with http_401 and the
like for a dead link, join_failed:<key> when the server refuses the join, network: … for a
page that did not load, join_timeout when the client never starts (joinTimeoutMs, default
90 s). The package's README lists them all, with what the Windows host does and does not do (no
navigation veto; native_module_missing when the host module is not linked into the app).
macOS was built and run for 0.3.0 (react-native-macos 0.83, macOS 26, Xcode 27): a
meeting was joined from a host app and the audio echo test, the chat (reading and sending), the
bottom sheets and leaving - back to the host with onLeave({ reason: 'left' }) - were exercised
against a live BigBlueButton server. A second host on react-native-macos 0.81.9 ran a meeting
with a second participant - remote camera and audio received, chat both ways, breakout rooms
created - and the defects it surfaced are fixed in 0.3.1: a remote camera that froze when another
app took focus, a timer that aborted release builds a minute after a session closed before
joining, the two react-native-macos 0.81.9 fixes above, buttons drawn at the left edge of the
status screens, and a black preview on a device without a camera (a Mac without one, the iOS
Simulator), where the camera sheet now says "Webcam not found" and keeps "Start sharing"
disabled; on a Mac whose only camera is external the capture names that camera (an iPhone used as a
Continuity Camera is listed once the host opts in with NSCameraUseContinuityCameraDeviceType). In
the chat on macOS and Windows, Return sends the message and Shift+Return inserts a newline.
Known issue on macOS: rows inside a bottom sheet (the leave menu, the audio device list) may not
take a click where they are drawn; the panels, dialogs and the bars work, and a host that drives
leaving itself (leaveSignal) is unaffected. Windows (2026-10-29, Windows 11,
react-native-windows 0.83.2, Visual Studio Build Tools 18): the WebView2 host joined a live meeting
and left cleanly; @bbb-mobile/windows-host builds, its WebRTC passes a loopback (camera and
microphone captured, two peer connections connected, remote audio and video received and drawn),
and the native client in a live meeting (2026-10-30, a BigBlueButton
server with LiveKit 1.9, a second participant on another client): join, the audio echo test and audio
(the microphone published, packets sent), the participant list, taking presenter, the chat (sent,
listed newest at the bottom, the composer clears), whiteboard drawing (strokes synced, other
participants' annotations drawn), the presentation slides, the camera (preview, published,
encoded) and screen sharing (published, received by the other participant), raising and lowering
the hand, leaving through the client's own menu (left: left) and through leaveSignal
(left: left (host_leave)), and rejoining in the same process. The icon font is installed for the current user on the first meeting
(%LOCALAPPDATA%\Microsoft\Windows\Fonts, a per-user install without elevation): react-native-windows
renders only installed fonts. Known on Windows: LiveKit's newer data-track channel is closed by
LiveKit servers that predate it (logged as an error in development, no effect on the meeting);
a dialog may need scrolling in a small window. Reports are welcome in the SDK repository's issues.
JavaScript setup
react-native-get-random-values must be the first import of the app (index.js). Babel needs two
plugins the React Native preset lacks: @babel/plugin-transform-export-namespace-from and
react-native-worklets/plugin, which goes last. patch-package applies the package's patches
(below).
npm install -D @babel/plugin-transform-export-namespace-from@7 patch-package@7 matters: the plugin's latest is Babel 8, whose peer @babel/core ^8 no React Native
template meets, so the unversioned install ends in ERESOLVE and the postinstall below then runs
without a patch-package binary.
// babel.config.js
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: ['@babel/plugin-transform-export-namespace-from', 'react-native-worklets/plugin'],
};The package ships the three patches a mobile host needs at the top of
node_modules/@bbb-mobile/bigbluebutton-mobile-sdk/patches/, for @livekit/react-native 3.0.0,
@livekit/react-native-webrtc 144.2.0 and react-native-view-shot 4.0.3. Copy those three FILES -
not the directory: its react-native-macos/ subfolder is for macOS hosts, patch-package reads
subfolders too, and with no react-native-macos installed the two copies in it make the run fail
(exit 1, under CI or not). Copy the three into the app's patches/ folder and add
"postinstall": "patch-package" to the app's scripts. npm runs that script for npm install without package names and for npm ci,
not for an install that names packages. Pin the three libraries at the patched versions, so that a
later release inside the peer ranges cannot break the patches, then run a plain install to apply
them:
npm install --save-exact @livekit/[email protected] @livekit/[email protected] [email protected]
npm install # no package names: runs postinstall, so patch-package applies the three patchesWithout the patches, the iOS build fails in react-native-view-shot.
@livekit/components-react and livekit-client must resolve to one copy in the app: a nested
second copy makes the meeting fail at startup with "No room provided". Check with
npm ls @livekit/components-react livekit-client and run npm dedupe if a copy is nested.
npm installs the peer dependencies; Yarn v1 does not, so add them to the app yourself (the list is
in this package's package.json). The meeting uses @livekit/react-native-webrtc: an app that
uses react-native-webrtc switches to it (same JavaScript API, the two cannot coexist). An app that
registers the WebRTC globals itself does that before calling
configureBigBlueButtonMeeting({ registerWebRtcGlobals: false }), which checks
navigator.mediaDevices and throws when it is missing.
Android host app
The Expo modules runtime goes into the native project. This package was tested with it wired by
hand (install-expo-modules stopped at Expo SDK 56 when this integration was written; its 0.18.x
releases list SDK 57 and were not tried with this package). The
integration guide
spells out each change:
settings.gradle: Expo autolinking and its version catalog;build.gradle:expo-root-projectand the JitPack repository, for LiveKit's audioswitch;MainApplication.kt:ExpoReactHostFactorywithjsMainModulePath = "index", andApplicationLifecycleDispatcher;MainActivity.kt:ReactActivityDelegateWrapper.
AndroidManifest.xml needs the meeting's permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />On the main activity, add android:supportsPictureInPicture="true" (the meeting's
picture-in-picture window) and locale|layoutDirection to android:configChanges. The meeting's
foreground service and its permissions (microphone, media playback and media projection service
types, notifications, Bluetooth) merge in from @bbb-mobile/sdk-host. minSdkVersion 24, the
React Native 0.86 default. Play Console: declare the foreground-service use cases microphone,
media playback and media projection.
iOS host app
- Deployment target: raise the app target to iOS 16.4 (Xcode: the app target > General > Minimum
Deployments, or
IPHONEOS_DEPLOYMENT_TARGET = 16.4in every build configuration ofios/<App>.xcodeproj/project.pbxproj). The React Native template starts at 15.1, and the Expo modules need 16.4. ios/Podfile: Expo's autolinkingrequireabove React Native's,platform :ios, '16.4',use_expo_modules!first in the app target, anduse_native_modules!with Expo's React Native config command; thenpod install. The tested app also builds with React Native's prebuilt core and dependencies and Expo's precompiled modules:RCT_USE_PREBUILT_RNCORE,RCT_USE_RN_DEPandEXPO_USE_PRECOMPILED_MODULESset to1at the top of the Podfile, beforeuse_expo_modules!reads them.AppDelegate.swift:AppDelegatesubclassesExpoAppDelegateand starts React Native through anExpoReactNativeFactory. The integration guide describes both changes.- Info.plist:
NSMicrophoneUsageDescription,NSCameraUsageDescription,NSBluetoothAlwaysUsageDescription,NSBluetoothPeripheralUsageDescription,NSLocalNetworkUsageDescription,NSPhotoLibraryUsageDescription,NSPhotoLibraryAddUsageDescription,UIBackgroundModes=audio,UIViewControllerBasedStatusBarAppearance=false(the React Native template's value) andio.livekit.reactnative.expo.ENABLE_MULTITASKING_CAMERA_ACCESS=true(the camera keeps running in picture-in-picture where iOS allows it). - Screen sharing from the device needs a Broadcast Upload Extension in the app
(guide);
pass
screensharePresenteronly then. On Android it is on by default from Android 10 (API 29); older versions cannot share the screen.
Example
One screen with a join URL field and a Join button; the meeting takes over the screen until the
user leaves or the meeting ends, then the leave reason shows. It is a trimmed copy of the app this
package is tested with. In a new React Native 0.86.3 app
(npx @react-native-community/cli@latest init MyApp --version 0.86.3), apply the settings above,
use these two files as index.js and App.tsx, then run npx react-native run-android or
npx react-native run-ios.
// index.js
import 'react-native-get-random-values'; // first import of the app
import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';
AppRegistry.registerComponent(appName, () => App);// App.tsx
import React, { useState } from 'react';
import { Button, Text, TextInput, View } from 'react-native';
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
import {
BigBlueButtonMeeting,
configureBigBlueButtonMeeting,
type LeaveInfo,
} from '@bbb-mobile/bigbluebutton-mobile-sdk';
configureBigBlueButtonMeeting({ clientType: 'NATIVE_MOBILE', appVersion: '1.0.0' });
export default function App() {
const [url, setUrl] = useState('');
const [joinUrl, setJoinUrl] = useState<string | null>(null);
const [lastLeave, setLastLeave] = useState<LeaveInfo | null>(null);
if (joinUrl) {
return (
<View style={{ flex: 1 }}>
<BigBlueButtonMeeting
joinUrl={joinUrl}
openLogoutUrl={false}
onLeave={(info) => {
setJoinUrl(null); // unmount the meeting
setLastLeave(info);
}}
/>
</View>
);
}
const trimmed = url.trim();
return (
<SafeAreaProvider>
<SafeAreaView style={{ flex: 1, padding: 16 }}>
<TextInput
value={url}
onChangeText={setUrl}
placeholder="https://<server>/html5client/join?sessionToken=..."
autoCapitalize="none"
autoCorrect={false}
keyboardType="url"
/>
<Button title="Join meeting" disabled={!trimmed} onPress={() => setJoinUrl(trimmed)} />
{lastLeave && (
<Text>
Left: {lastLeave.reason}
{lastLeave.detail ? ` (${lastLeave.detail})` : ''}
</Text>
)}
</SafeAreaView>
</SafeAreaProvider>
);
}Changelog
0.6.0
- The native meeting client on Windows.
<BigBlueButtonMeeting/>on react-native-windows 0.83+ (new architecture) renders the same client as on Android, iOS and macOS when the app links the new package@bbb-mobile/windows-host0.1.0 (installed with this package, autolinked): WebRTC for react-native-windows, the native side of@livekit/react-native-webrtc(its module, events, payloads andRTCVideoView) on a prebuilt libwebrtc the build downloads once, LiveKit's audio session module, and the host services the client's Windows adapter variants use (synchronous storage, the file dialogs, keep-awake, the clipboard, the icon font). The animation, gesture, bottom-sheet and safe-area libraries have no Windows build: the package ships JavaScript stand-ins and the Metro helperwithBigBlueButtonWindows(@bbb-mobile/bigbluebutton-mobile-sdk/metro) that a Windows host wraps its Metro config with.getMeetingRenderer()isnativewith the host module,webwithout it;renderer="native"no longer ends withunsupportedon Windows. Not on Windows: end-to-end encryption, video effects, picture in picture; screen sharing captures the primary screen. - No change on Android, iOS or macOS.
- Upgrading:
npm install @bbb-mobile/[email protected]; Windows hosts install the native client's libraries (see "macOS and Windows"), wrap their Metro config withwithBigBlueButtonWindows, runnpx react-native autolink-windowsand rebuild.
0.5.0
- Windows runs.
<BigBlueButtonMeeting/>and<BigBlueButtonPlayback/>on react-native-windows rendered throughreact-native-webview, whose Windows implementation is written for the old architecture; react-native-windows 0.82 and later no longer load it, so a host on 0.83 got "View config not found for component RCTWebView" instead of a meeting.@bbb-mobile/meeting-webview0.3.0 ships its own WebView2 host for Windows: a C++ TurboModule (windows/BbbMeetingWebView, autolinked) that keeps one WebView2 per component in a window owned by the app's main window, over the component's rectangle. With it the user agent carriesclientType/appVersionon Windows too, load and HTTP errors are reported (network: host_name_not_resolved,http_404), and a host without the module getsonLeave({ reason: 'error', detail: 'native_module_missing' }). No react-native-webview is needed on Windows; an app that has it for other platforms turns its Windows project off inreact-native.config.js. The host's own React Native content cannot be drawn over the meeting there (the WebView is a window above the app's). - macOS and large screens (tablets, unfolded foldables): Messages, Participants, Notes, Polls, Breakouts, Settings and the other panels open as a centred popup over the dimmed meeting (at most 560 x 760 points; a click outside closes it) instead of covering the window, and the meeting keeps its layout and controls under it. The stage keeps its state while a panel opens and closes; phones keep the full-screen panel and the chat sheet. The presentation upload is a centred dialog there instead of covering the window.
- Upgrading:
npm install @bbb-mobile/[email protected]; Windows hosts runnpx react-native autolink-windowsand rebuild.
0.4.0
- External video in the meeting plays on every server: YouTube, Vimeo and media-file links shared with "Play video from link" play in a native player synchronised with the presenter (play, pause, seek, rate), where before the stage said playback was not available unless the server had the html5 embed page.
- Recording playback on every platform:
<BigBlueButtonPlayback/>renders a BigBlueButton recording from its playback URL (the presentation player, the video format, or any other playback URL) in the platform WebView, withonReady,onProgress,onEnded,onClose,closeSignalandstartAt; links out of the recording open in the system browser. Video links play too (YouTube, Vimeo, media files), through the site's embedded player. It is@bbb-mobile/meeting-webview0.2.0's component, re-exported by the Android / iOS / macOS entry and the Windows entry alike; the Windows bundle still contains nothing of the native client. - Includes everything 0.3.1 (unpublished) corrected: the peer ranges a fresh npm install needs,
the react-native-macos patches in
patches/react-native-macos/, and the macOS and all-platform fixes listed under 0.3.1.
0.3.1
- macOS: screen sharing from the Mac. The shipped WebRTC fork patch captures the main display with
ScreenCaptureKit (macOS 12.3+, cursor included, up to 1920 px, 15 fps) and publishes it through
the same LiveKit path the phones use; the first share asks for the Screen Recording permission.
The host app must call
LivekitReactNative.setup()so LiveKit's simulcast encoder factory is installed - without it the single VP8 encoder refuses the meeting's screen-share layers and nothing is encoded. - macOS: the presentation upload works, through
macos/BbbMacFilePicker.swiftand.m(anNSOpenPanel) that the host app adds to its target; the adapter used to have no picker at all there, so "Upload a document" and "Upload an image" did nothing. - macOS: react-native-svg 15.15.5 or newer is required. 15.15.3 draws nothing under the new architecture there, which left the slide, every whiteboard annotation and the SVG tool icons invisible - a presenter's own drawings reached everyone but their own screen.
- All platforms: no screen share was ever shown to a viewer, and a presenter's share was stopped
after ten seconds as "not acknowledged". The
meetingsubscription asked forcomponentsFlags.isEtherpadSharedNotes(and the notes query forsharedNotesEditor), which the server does not have; the whole subscription was rejected, so the flags never arrived and the client never subscribed to screen shares. Neither field is read anywhere and both are gone. - All platforms: an uploaded presentation is listed under its real name again. React Native percent-encodes the multipart filename and the server stores what it receives, so "slides v2 (1).pdf" became "slides%20v2%20(1).pdf"; the uploader writes that header itself now.
- macOS: a click on the meeting stage hides the chrome and the next click brings it back (it still
never hides on its own there), and the newest chat message is at the bottom of the list again -
react-native-macos skips the inversion of an
invertedlist, but only its old architecture inverts the scroll view natively, so the list is inverted by the SDK there. - A fresh
npm installbundles again: the package now namesexpo-asset ~57.0.20as a peer. Expo SDK 58 is out, and without that peer npm hoisted itsexpo-assetnext toexpo57 (throughexpo-audio'sexpo-asset@*peer);expo-fontthen importedexpo/internal/bundle-origin, which expo 57 lacks, and the iOS and Android bundles stopped at "Unable to resolve module". Yarn v1 and pnpm hosts were not affected. @livekit/react-native3.1.0 peers the WebRTC fork^150, so the former^3.0.0peer ended a plain npm install in ERESOLVE against the fork range: the peers are now~3.0.0and~144.2.0, the versions the shipped patches are for.- The two
react-native-macospatches moved topatches/react-native-macos/; the top ofpatches/holds the same three files as 0.2.0 again (0.3.0 put five there, and a mobile host that copied the folder had patch-package fail on the two with no package to apply to). - This page: the Babel plugin is installed as
@7(itslatestis Babel 8),react-native-webviewis pinned to 13.x in the desktop commands (itslatestis 14, outside the peer range), the macOS react/react-dom note is right for a stock React Native 0.83 app, and the companion pages of@bbb-mobile/meeting-webview0.1.1 and@bbb-mobile/video-effects0.1.2 no longer call the WebView renderer the SDK's macOS path or quote an old pin. - macOS: a remote camera no longer freezes on its last frame when another app takes focus (the
LiveKit module patch counted a video as hidden unless the app was active, and react-native-macos
reports
inactivefor a window that merely lost focus; onlybackgroundhides a video there now). In the chat, Return sends and Shift+Return inserts a newline. On a device without a camera the camera sheet says "Webcam not found" and keeps "Start sharing" disabled instead of publishing a black tile (all platforms). - react-native-macos 0.81.9 hosts: the shipped patch for that line also fixes the display link's clock (it read 0 while the link was stopped, so every UI-thread frame measured 10 ms, Reanimated animations never advanced and the joined meeting was never drawn) and, like the 0.83.0 copy, applies a non-finite view transform as identity instead of freezing the window.
- All platforms: a session that closed before the join completed (a failed join, the return from a breakout room) threw "Authentication timeout" a minute later, a fatal error in release builds; the timer is cleared when the session goes away. The error, meeting-ended, guest-wait and unsupported-meeting screens centre their buttons.
- Upgrading from 0.3.0:
npm install @bbb-mobile/[email protected], then look at the app'spatches/folder - if the tworeact-native-macos+*.patchfiles are there on a mobile host, delete them (with them present patch-package fails andreact-native-view-shotstays unpatched); a macOS host keeps exactly one, and copies that one and@livekit+react-native+3.0.0.patchfrom the package again (both gained hunks), then deletesnode_modules/@livekit/react-nativeandnode_modules/react-native-macosso thatnpm installlets patch-package apply each whole patch to a pristine copy. Then a plainnpm install. A mobile host may keep its 0.3.0 copy of the LiveKit module patch (the new hunk only changes macOS); nothing else changes there.
0.3.0
- macOS: the native meeting client runs on react-native-macos (React Native 0.83). The host
adapter has macOS variants without Expo native modules; the LiveKit module patch makes
livekit-react-nativebuild for macOS. Screen sharing, picture in picture, video effects, alert sounds, file pickers and sharing are not available there yet. - Windows:
<BigBlueButtonMeeting/>renders the server's html5 client in WebView2 on react-native-windows (no WebRTC exists for that platform), same props and leave contract; new package@bbb-mobile/meeting-webview0.1.0 (installed with this package;react-native-webviewis its native dependency). Nothing of the native client is bundled on Windows. - New props
renderer(auto/native/web),webViewPropsandjoinTimeoutMs, andgetMeetingRenderer(): the web renderer is also available on Android and iOS. @bbb-mobile/video-effects0.1.1: declared for Android and iOS only, so that Expo autolinking no longer offers its iOS-only pod to a macOS target. No change on Android or iOS.- Upgrading from 0.2.0: copy both LiveKit patches into the app's
patches/again (they gained the macOS hunks; iOS behaviour is unchanged), then deletenode_modules/@livekit/react-nativeandnode_modules/@livekit/react-native-webrtcand runnpm installso patch-package applies each whole patch to a pristine copy (a copy that already carries the old patch makes it fail).
0.2.0
- Camera video effects in the meeting UI: background blur and scenes, colour filters, AR effects,
touch-up and low light, on by default;
videoEffects={false}turns them off. - New native module
@bbb-mobile/video-effects0.1.0, installed with this package: runpod installand rebuild the app. On Android it adds ML Kit selfie segmentation and face detection, about 20 MB of native code per ABI. - Upgrading from 0.1.0: copy
patches/@livekit+react-native-webrtc+144.2.0.patchinto the app'spatches/again (it gained a one-line fix), then deletenode_modules/@livekit/react-native-webrtcand runnpm installso patch-package applies the new version.
0.1.0
- First release: the BigBlueButton mobile meeting client as a React Native package
(
<BigBlueButtonMeeting/>,configureBigBlueButtonMeeting()) for BigBlueButton 4.0 servers, with the Expo native modules@bbb-mobile/pip,@bbb-mobile/downloadsand@bbb-mobile/sdk-host, and three patch-package patches.
The changelog of every SDK (Android, iOS, Flutter, React Native) is in the SDK repository's CHANGELOG.md.
Compatibility
| Package | BigBlueButton server | React Native | Expo SDK | @bbb-mobile modules | Min Android | Min iOS | macOS / Windows |
|---|---|---|---|---|---|---|---|
| 0.5.0 | 4.0.x (3.0.x through the WebView); recordings of any server with the presentation player | 0.86.3 (Android, iOS); 0.83 on the desktop forks | 57 (expo ~57.0.22, expo-asset ~57.0.20); none on macOS and Windows | pip, downloads, sdk-host 0.1.0; video-effects 0.1.2; meeting-webview 0.3.0; windows-host 0.1.0 | 7.0 (API 24) | 16.4 | macOS 14 (react-native-macos 0.83 or 0.81.9 with the matching shipped patch, native client); Windows 10/11 (react-native-windows 0.83+ new architecture, native client with the windows-host module, WebView2 through the meeting-webview host) |
| 0.4.0 | 4.0.x (3.0.x through the WebView); recordings of any server with the presentation player | 0.86.3 (Android, iOS); 0.83 on the desktop forks | 57 (expo ~57.0.22, expo-asset ~57.0.20); none on macOS | pip, downloads, sdk-host 0.1.0; video-effects 0.1.2; meeting-webview 0.2.0 | 7.0 (API 24) | 16.4 | macOS 14 (react-native-macos 0.83 or 0.81.9 with the matching shipped patch, native client); Windows 10/11 (react-native-windows 0.83+, WebView2) |
| 0.3.1 | 4.0.x (3.0.x through the WebView) | 0.86.3 (Android, iOS); 0.83 on the desktop forks | 57 (expo ~57.0.22, expo-asset ~57.0.20); none on macOS | pip, downloads, sdk-host 0.1.0; video-effects 0.1.2; meeting-webview 0.1.1 | 7.0 (API 24) | 16.4 | macOS 14 (react-native-macos 0.83 or 0.81.9 with the matching shipped patch, native client); Windows 10/11 (react-native-windows 0.83+, WebView2) |
| 0.3.0 | 4.0.x (3.0.x through the WebView) | 0.86.3 (Android, iOS); 0.83 on the desktop forks | 57 (expo ~57.0.22); none on macOS | pip, downloads, sdk-host 0.1.0; video-effects 0.1.1; meeting-webview 0.1.0 | 7.0 (API 24) | 16.4 | macOS 14 (react-native-macos 0.83, native client); Windows 10/11 (react-native-windows 0.83+, WebView2) |
| 0.2.0 | 4.0.x | 0.86.3 | 57 (expo ~57.0.22) | pip, downloads, sdk-host, video-effects: all 0.1.0 | 7.0 (API 24) | 16.4 | - |
| 0.1.0 | 4.0.x | 0.86.3 | 57 (expo ~57.0.22) | pip, downloads, sdk-host: all 0.1.0 | 7.0 (API 24) | 16.4 | - |
React Native is the version each release was built and tested with. 0.3.1 and later peer
@livekit/react-native ~3.0.0 and @livekit/react-native-webrtc ~144.2.0 (earlier releases
declared caret ranges, which LiveKit 3.1's move to the fork's 150 line broke). The full matrix,
native SDKs included, is in
VERSIONS.md.
License
LGPL-3.0 (the LICENSE file in this package), like BigBlueButton, whose meeting client this
package contains.
