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

expo-livekit-screen-share

v0.2.0

Published

Expo config plugin for LiveKit screen sharing on iOS (Broadcast Upload Extension) and Android (foreground service)

Readme

expo-livekit-screen-share

Expo config plugin that enables screen sharing for LiveKit React Native apps on iOS and Android.

What it does

iOS

  • Creates a Broadcast Upload Extension target in your Xcode project
  • Downloads the Jitsi reference implementation Swift files during prebuild (cached locally)
  • Configures App Groups for inter-process communication between app and extension
  • Sets up Info.plist, entitlements, and Xcode build settings automatically

Android

  • Adds FOREGROUND_SERVICE_MEDIA_PROJECTION permission to AndroidManifest.xml
  • Enables LiveKit's screen share foreground service

Installation

npx expo install expo-livekit-screen-share

Configuration

Add the plugin to your app.json or app.config.js:

{
  "plugins": ["expo-livekit-screen-share"]
}

Options

All options are optional with sensible defaults:

{
  "plugins": [
    ["expo-livekit-screen-share", {
      "ios": {
        "extensionName": "ScreenShareExtension",
        "appGroupIdentifier": "group.com.example.myapp"
      },
      "android": {
        "enableScreenShareService": true,
        "foregroundServicePermission": true
      }
    }]
  ]
}

| Option | Platform | Default | Description | |--------|----------|---------|-------------| | ios.extensionName | iOS | "ScreenShareExtension" | Name of the Broadcast Upload Extension target | | ios.appGroupIdentifier | iOS | "group.{bundleIdentifier}" | Custom App Group identifier (if your project uses a different naming convention) | | android.enableScreenShareService | Android | true | Enable LiveKit's foreground service for screen sharing | | android.foregroundServicePermission | Android | true | Add FOREGROUND_SERVICE_MEDIA_PROJECTION permission |

iOS Setup (Apple Developer Portal)

Before building, you need to register identifiers in the Apple Developer Portal. Repeat these steps for each environment (development, staging, production):

1. Register an App Group

Identifiers > + > App Groups:

  • Identifier: group.{your.bundle.identifier} (e.g. group.com.example.myapp)

2. Add App Group to your main App ID

Identifiers > find your App ID > Edit > Capabilities > App Groups > select the group from step 1.

3. Register Extension Bundle ID

Identifiers > + > App IDs > type App:

  • Bundle ID: {your.bundle.identifier}.ScreenShareExtension
  • Enable App Groups capability > select the same group

4. Provisioning

If using Xcode Automatic Signing (development builds), Xcode handles provisioning profiles automatically.

For EAS Build, add appExtensions to your config:

// app.config.js
extra: {
  eas: {
    build: {
      experimental: {
        ios: {
          appExtensions: [{
            targetName: 'ScreenShareExtension',
            bundleIdentifier: `${bundleIdentifier}.ScreenShareExtension`,
            entitlements: {
              'com.apple.security.application-groups': [
                `group.${bundleIdentifier}`,
              ],
            },
          }],
        },
      },
    },
  },
}

Usage in your app

Start screen sharing

import { useRoomContext } from '@livekit/react-native';

// Android — call directly:
await room.localParticipant.setScreenShareEnabled(true);

// iOS — show broadcast picker first:
import { ScreenCapturePickerView } from '@livekit/react-native-webrtc';
import { findNodeHandle, NativeModules, Platform } from 'react-native';

// Mount the invisible picker view somewhere in your component tree:
<ScreenCapturePickerView ref={pickerRef} />

// Then trigger it:
if (Platform.OS === 'ios') {
  const tag = findNodeHandle(pickerRef.current);
  await NativeModules.ScreenCapturePickerViewManager.show(tag);
}
await room.localParticipant.setScreenShareEnabled(true);

Check screen share state

import { useLocalParticipant } from '@livekit/react-native';

const { isScreenShareEnabled } = useLocalParticipant();

How it works

The iOS Broadcast Upload Extension runs as a separate process that captures the screen via ReplayKit. It communicates with the main app through a Unix domain socket (rtc_SSFD) in the shared App Group container. The @livekit/react-native-webrtc native module (ScreenCapturer) listens on this socket and feeds received frames into the WebRTC pipeline.

Swift source files are downloaded from the Jitsi reference implementation during expo prebuild and cached in node_modules/.cache/expo-livekit-screen-share/. Delete this directory to force re-download.

Troubleshooting

Download fails during prebuild

If you're building offline or behind a firewall, manually download the Swift files from Jitsi SDK samples and place them in node_modules/.cache/expo-livekit-screen-share/.

iOS screen share doesn't start

  • Verify App Group identifiers match between the main app and extension
  • Check that RTCScreenSharingExtension and RTCAppGroupIdentifier are set in the main app's Info.plist
  • Ensure the extension's provisioning profile includes the App Group capability

License

MIT