npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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

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-sdk

react-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, false when the app already renders a GestureHandlerRootView;
  • 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) or native; webViewProps passes 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() is native.
  • 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-webrtc on 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 for windows. getMeetingRenderer() is native with the host module linked and web without 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 its react-native-macos/ subfolder. The two LiveKit ones carry macOS hunks (the module patch makes livekit-react-native build 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), and react-native-macos+<version>.patch adds what the fork is missing: a Fabric <Modal> host for macOS (without it the first dialog the meeting opens throws Exception in HostFunction and 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's patches/ 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 leave react-native-view-shot's patch out too, that library is not installed on macOS. Then the same babel.config.js plugins and first import as on mobile; cd macos && pod install (autolinking links the pods whose podspec supports macOS and skips the iOS-only ones); NSCameraUsageDescription and NSMicrophoneUsageDescription in Info.plist, the camera and audio-input entitlements; the SDK's icon font packages/bbb-ui-native/assets/fonts/bbb-icons.ttf added to the app's Copy Bundle Resources with ATSApplicationFontsPath = . in Info.plist. A sandboxed app also needs com.apple.security.network.server: with only network.client the 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 call LivekitReactNative.setup() (from the livekit_react_native module) 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's macos/BbbMacFilePicker.swift and .m to the app target (an NSOpenPanel; 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-windows after the install (run-windows runs it too) links node_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's RNSVG into 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 } } in react-native.config.js; the project is old-architecture only, the library's JavaScript is still bundled). In metro.config.js, wrap the config with withBigBlueButtonWindows from @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 same babel.config.js plugins 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 patches

Without 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-project and the JitPack repository, for LiveKit's audioswitch;
  • MainApplication.kt: ExpoReactHostFactory with jsMainModulePath = "index", and ApplicationLifecycleDispatcher;
  • 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.4 in every build configuration of ios/<App>.xcodeproj/project.pbxproj). The React Native template starts at 15.1, and the Expo modules need 16.4.
  • ios/Podfile: Expo's autolinking require above React Native's, platform :ios, '16.4', use_expo_modules! first in the app target, and use_native_modules! with Expo's React Native config command; then pod 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_DEP and EXPO_USE_PRECOMPILED_MODULES set to 1 at the top of the Podfile, before use_expo_modules! reads them.
  • AppDelegate.swift: AppDelegate subclasses ExpoAppDelegate and starts React Native through an ExpoReactNativeFactory. 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) and io.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 screensharePresenter only 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-host 0.1.0 (installed with this package, autolinked): WebRTC for react-native-windows, the native side of @livekit/react-native-webrtc (its module, events, payloads and RTCVideoView) 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 helper withBigBlueButtonWindows (@bbb-mobile/bigbluebutton-mobile-sdk/metro) that a Windows host wraps its Metro config with. getMeetingRenderer() is native with the host module, web without it; renderer="native" no longer ends with unsupported on 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 with withBigBlueButtonWindows, run npx react-native autolink-windows and rebuild.

0.5.0

  • Windows runs. <BigBlueButtonMeeting/> and <BigBlueButtonPlayback/> on react-native-windows rendered through react-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-webview 0.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 carries clientType / appVersion on Windows too, load and HTTP errors are reported (network: host_name_not_resolved, http_404), and a host without the module gets onLeave({ 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 in react-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 run npx react-native autolink-windows and 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, with onReady, onProgress, onEnded, onClose, closeSignal and startAt; 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-webview 0.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.swift and .m (an NSOpenPanel) 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 meeting subscription asked for componentsFlags.isEtherpadSharedNotes (and the notes query for sharedNotesEditor), 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 inverted list, but only its old architecture inverts the scroll view natively, so the list is inverted by the SDK there.
  • A fresh npm install bundles again: the package now names expo-asset ~57.0.20 as a peer. Expo SDK 58 is out, and without that peer npm hoisted its expo-asset next to expo 57 (through expo-audio's expo-asset@* peer); expo-font then imported expo/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-native 3.1.0 peers the WebRTC fork ^150, so the former ^3.0.0 peer ended a plain npm install in ERESOLVE against the fork range: the peers are now ~3.0.0 and ~144.2.0, the versions the shipped patches are for.
  • The two react-native-macos patches moved to patches/react-native-macos/; the top of patches/ 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 (its latest is Babel 8), react-native-webview is pinned to 13.x in the desktop commands (its latest is 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-webview 0.1.1 and @bbb-mobile/video-effects 0.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 inactive for a window that merely lost focus; only background hides 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's patches/ folder - if the two react-native-macos+*.patch files are there on a mobile host, delete them (with them present patch-package fails and react-native-view-shot stays unpatched); a macOS host keeps exactly one, and copies that one and @livekit+react-native+3.0.0.patch from the package again (both gained hunks), then deletes node_modules/@livekit/react-native and node_modules/react-native-macos so that npm install lets patch-package apply each whole patch to a pristine copy. Then a plain npm 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-native build 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-webview 0.1.0 (installed with this package; react-native-webview is its native dependency). Nothing of the native client is bundled on Windows.
  • New props renderer (auto / native / web), webViewProps and joinTimeoutMs, and getMeetingRenderer(): the web renderer is also available on Android and iOS.
  • @bbb-mobile/video-effects 0.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 delete node_modules/@livekit/react-native and node_modules/@livekit/react-native-webrtc and run npm install so 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-effects 0.1.0, installed with this package: run pod install and 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.patch into the app's patches/ again (it gained a one-line fix), then delete node_modules/@livekit/react-native-webrtc and run npm install so 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/downloads and @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.