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

@upscopeio/react-native-sdk

v2026.7.3

Published

React Native SDK for Upscope cobrowsing

Downloads

1,136

Readme

@upscopeio/react-native-sdk

React Native SDK for Upscope cobrowsing — screen sharing, agent annotations, and remote control for iOS and Android.

Requirements

  • React Native 0.76+
  • iOS 14+
  • Android API 26+ (Android 8.0 Oreo)
  • New Architecture (Fabric + TurboModules) required

Installation

npm install @upscopeio/react-native-sdk

iOS

Run pod install — the native UpscopeSDK is linked automatically via this SDK's podspec dependency, so its version always matches the published package. No extra steps.

cd ios && pod install

By default the SDK shares only your app's UI. To let agents view the visitor's entire device, see Full device sharing (iOS).

Android

No extra steps — the native module and Upscope Android SDK are linked automatically via autolinking.

Quick Start

Initialize in your app entry point (before rendering any components that use Upscope hooks):

import Upscope from '@upscopeio/react-native-sdk';

// App.tsx — call once, as early as possible
Upscope.initialize({
  apiKey: 'your-api-key',
  autoConnect: true,
  requireAuthorizationForSession: true,
});

// Identify the visitor
Upscope.updateConnection({
  uniqueId: 'user-123',
  callName: 'Jane Doe',
  tags: ['support'],
  identities: ['[email protected]'],
  integrationIds: ['intercom:user123'],
  metadata: { plan: 'premium' },
});

If autoConnect is false, call Upscope.connect() manually after initialization.

Hooks

All hooks are reactive — they re-render the component when the underlying state changes.

useConnectionState

Returns the current WebSocket connection state.

import { useConnectionState } from '@upscopeio/react-native-sdk';

function StatusBadge() {
  const state = useConnectionState();
  // state: 'inactive' | 'connecting' | 'connected' | 'reconnecting' | 'error'
  return <Text>Connection: {state}</Text>;
}

useSessionState

Returns the current co-browsing session state.

import { useSessionState } from '@upscopeio/react-native-sdk';

function SessionBanner() {
  const session = useSessionState();
  // session: 'inactive' | 'pendingRequest' | 'active' | 'paused' | 'ended'
  if (session !== 'active') return null;
  return <Text>Session in progress</Text>;
}

useShortId

Returns the SDK short ID (used to look up the visitor in the Upscope dashboard), or null until assigned.

import { useShortId } from '@upscopeio/react-native-sdk';

function VisitorId() {
  const shortId = useShortId();
  return <Text>Short ID: {shortId ?? 'pending...'}</Text>;
}

useLookupCode

Returns the current lookup code shown to the visitor for phone-based agent lookup, or null until emitted.

import { useLookupCode } from '@upscopeio/react-native-sdk';

function LookupCode() {
  const code = useLookupCode();
  return <Text>Your code: {code ?? '—'}</Text>;
}

useRemoteControlState

Returns whether an agent currently has remote control of the device.

import { useRemoteControlState } from '@upscopeio/react-native-sdk';

function ControlBadge() {
  const state = useRemoteControlState();
  // state: 'inactive' | 'pendingRequest' | 'active'
  return <Text>Remote control: {state}</Text>;
}

useFullDeviceSharingState

Returns whether full-device (broadcast) sharing is currently running.

import { useFullDeviceSharingState } from '@upscopeio/react-native-sdk';

function SharingBadge() {
  const state = useFullDeviceSharingState();
  // state: 'inactive' | 'pendingRequest' | 'active'
  return <Text>Full-device sharing: {state}</Text>;
}

useUpscope

Returns a stable object of imperative action methods — safe to destructure and pass as deps.

import { useUpscope } from '@upscopeio/react-native-sdk';

function Controls() {
  const { connect, disconnect, stopSession, sendCustomMessage } = useUpscope();
  return (
    <>
      <Button title="Connect" onPress={connect} />
      <Button title="Disconnect" onPress={disconnect} />
      <Button title="End Session" onPress={stopSession} />
    </>
  );
}

Events

Subscribe to native events imperatively via Upscope.addListener. Always call .remove() on cleanup.

import Upscope from '@upscopeio/react-native-sdk';
import { useEffect } from 'react';

useEffect(() => {
  const sub = Upscope.addListener('sessionStarted', ({ agentName }) => {
    console.log(`Session started with ${agentName}`);
  });
  return () => sub.remove();
}, []);

Event names

| Event name | Payload type | Description | | ------------------------- | ----------------------------- | ---------------------------------------- | | connectionStateChanged | ConnectionStateChangedEvent | Connection state transitioned | | sessionStateChanged | SessionStateChangedEvent | Session state transitioned (current-value)| | sessionStarted | SessionStartedEvent | Agent joined and session is active | | sessionEnded | SessionEndedEvent | Session ended (includes reason) | | customMessageReceived | CustomMessageEvent | Arbitrary string from a viewer | | error | UpscopeError | Non-fatal SDK error | | viewerJoined | Viewer | New viewer connected | | viewerLeft | ViewerLeftEvent | Viewer disconnected | | viewerCountChanged | ViewerCountChangedEvent | Total viewer count changed | | shortIdChanged | ShortIdChangedEvent | Short ID assigned or rotated | | lookupCodeChanged | LookupCodeChangedEvent | Lookup code issued or changed | | remoteControlStateChanged | RemoteControlStateChangedEvent | Agent gained or lost remote control | | fullDeviceSharingStateChanged | FullDeviceSharingStateChangedEvent | Full-device sharing started or stopped | | fullDeviceRequest | FullDeviceRequestEvent | Agent requested full-device sharing — includes the requesting agentName; answer with respondToFullDeviceRequest | | controlRequest | ControlRequestEvent | Agent requested remote control — includes the requesting agentName; answer with respondToControlRequest |

View Masking

Wrap any sensitive content in UpscopeMasked to hide it from the agent's view during a session. The masked region appears as a solid block in the screen share.

import { UpscopeMasked } from '@upscopeio/react-native-sdk';

function PaymentForm() {
  return (
    <View>
      <Text>Card number</Text>
      <UpscopeMasked>
        <TextInput secureTextEntry placeholder="•••• •••• •••• ••••" />
      </UpscopeMasked>
    </View>
  );
}

UpscopeMasked accepts all standard ViewProps in addition to children.

Configuration

Pass a UpscopeConfig object to Upscope.initialize():

interface UpscopeConfig {
  apiKey: string;                        // Required. Your Upscope API key.
  requireAuthorizationForSession?: boolean; // Show a prompt before allowing a session. Default: true.
  autoConnect?: boolean;                 // Connect on initialize(). Default: false.
  region?: string;                       // Override the server region.
  showTerminateButton?: boolean;         // Show an end-session button during a session.
  showUpscopeLink?: boolean;             // Show the "Powered by Upscope" link. Hiding it requires the whitelabel feature on the account.
  authorizationPromptTitle?: string;     // Custom title for the session request dialog.
  authorizationPromptMessage?: string;   // Custom message for the session request dialog.
  endOfSessionMessage?: string;          // Message shown when a session ends.
  stopSessionText?: LocalizedString;     // Label for the terminate-session button.
  allowRemoteClick?: boolean;            // Allow agent to send tap events. Default: true.
  allowRemoteScroll?: boolean;           // Allow agent to send scroll events. Default: true.
  requireControlRequest?: boolean;       // Require visitor approval before remote control starts.
  broadcastAppGroupId?: string;          // iOS only. App Group shared with the Broadcast Upload Extension (enables full-device sharing).
  broadcastExtensionBundleId?: string;   // iOS only. Bundle id of the Broadcast Upload Extension.
}

// Translation fields accept either a plain string or a language-keyed map.
// Keys are BCP-47 language tags; the native SDK picks the best match for the
// device's preferred languages.
type LocalizedString = string | { [language: string]: string };

Example:

Upscope.initialize({
  apiKey: "…",
  stopSessionText: { en: "Stop", it: "Ferma", "pt-PT": "Parar" },
});

Full device sharing (iOS)

Full device sharing lets the agent see the entire device screen (other apps, home screen) via ReplayKit. It requires a Broadcast Upload Extension target in your app — npm packages can't add app extension targets, so this is a one-time manual setup (~10 minutes). Without it, the agent's "Full app sharing" button is hidden.

Android needs no setup: it uses MediaProjection, and the required foreground-service permissions are merged automatically from the SDK's manifest.

1. Add the extension target

In Xcode: File → New → Target → Broadcast Upload Extension. Name it (e.g. YourAppBroadcast), uncheck "Include UI Extension".

2. Replace the generated SampleHandler

import UpscopeSDK

class SampleHandler: UpscopeSampleHandler {}

3. Add an App Group to BOTH targets

In Signing & Capabilities for your app target and the extension target, add the App Groups capability with the same group, e.g. group.com.yourcompany.yourapp.

4. Declare the group in the extension's Info.plist

<key>UpscopeAppGroupId</key>
<string>group.com.yourcompany.yourapp</string>

Also make sure NSExtension > RPBroadcastProcessMode is 2 (sample-buffer mode); some Xcode template versions omit it. See the example app's Info.plist.

5. Add the extension pod

# Podfile (top level, alongside your app target)
target 'YourAppBroadcast' do
  pod 'UpscopeSDK/BroadcastExtension'
end

Run pod install.

6. Pass the keys at initialization

Upscope.initialize({
  apiKey: 'your-api-key',
  broadcastAppGroupId: 'group.com.yourcompany.yourapp',
  broadcastExtensionBundleId: 'com.yourcompany.yourapp.YourAppBroadcast',
});

broadcastAppGroupId enables the feature (the agent's button appears); broadcastExtensionBundleId preselects your extension in the iOS picker.

Notes

  • The App Group ID must match in three places: both targets' entitlements, the extension's Info.plist (UpscopeAppGroupId), and broadcastAppGroupId.
  • Test on a physical device — ReplayKit broadcasts are unreliable on the simulator.
  • Full-device capture cannot mask views. Set disableFullScreenWhenMasked: true to automatically end full-device sharing whenever masked content is on screen.
  • Expo managed workflow is not supported (extension targets require a config plugin; not currently provided).
  • A complete working setup is in example/ios (UpscopeExampleBroadcast target).

API Reference

Initialization

| Method | Description | | ----------------------------------- | --------------------------------------------------- | | initialize(config) | Initialize the SDK. Call once before everything else. | | connect() | Open the WebSocket connection. | | disconnect() | Close the WebSocket connection. | | reset(reconnect?) | Reset connection state. Reconnects by default. |

Visitor Identity

| Method | Description | | ----------------------------------- | --------------------------------------------------- | | updateConnection(params) | Set/update uniqueId, callName, tags, identities, integrationIds, metadata. |

Session

| Method | Description | | ----------------------------------- | --------------------------------------------------- | | stopSession() | Terminate the active session. | | requestAgent() | Request that an agent join. | | cancelAgentRequest() | Cancel a pending agent-join request. | | stopRemoteControl() | Revoke the agent's remote control, keep the session.| | stopFullDeviceSharing() | Stop full-device sharing, revert to in-app, keep the session. | | respondToFullDeviceRequest(id, accept) | Answer a fullDeviceRequest event. | | respondToControlRequest(id, accept) | Answer a controlRequest event. |

Data

| Method | Returns | Description | | ----------------------------------- | -------------------- | ------------------------------------- | | getShortId() | Promise<string \| null> | Resolve the current short ID. | | getWatchLink() | Promise<string \| null> | Resolve the session watch link. | | getLookupCode() | void | Trigger a lookupCodeChanged event. |

Messaging

| Method | Description | | ----------------------------------- | --------------------------------------------------- | | sendCustomMessage(message) | Send a string to all connected viewers. |

Events

| Method | Description | | ----------------------------------- | --------------------------------------------------- | | addListener(eventName, callback) | Subscribe to an event. Returns { remove() }. |

Example App

A full-featured example app is included in example/. It demonstrates initialization, connection, visitor identification, view masking, and event logging.

Running the example

# Install dependencies
cd example
npm install

# iOS
cd ios && pod install && cd ..
npm run ios

# Android
npm run android

The app prompts for an API key on launch, then shows all SDK features in a scrollable demo screen.

Troubleshooting

"SDK not initialized"Upscope.initialize() must be called before connect() or any hook mounts.

Session prompt never appears — Ensure requireAuthorizationForSession: true (default). On Android, the app must be in the foreground.

Masked views visible to agentUpscopeMasked must be a direct native view wrapper. Confirm autolinking ran and pod install completed on iOS.

TypeScript errors on event payloads — Import the specific payload type from @upscopeio/react-native-sdk, e.g. import type { SessionStartedEvent } from '@upscopeio/react-native-sdk'.

License

MIT