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

@truncatetechnologies/streamsdk-rn

v1.0.2

Published

Truncate Video SDK for React Native — live streaming, multi-party video rooms.

Readme

StreamSDK — React Native

npm version license

React Native SDK for StreamSDK — real-time live streaming and multi-party video rooms for iOS and Android. Built on react-native-webrtc + mediasoup-client.

Full documentation: https://streamsdk.io/docs — includes guides, API reference, token server setup, and platform quickstarts.


Features

  • Live streaming (publisher) — WHIP ingest via WebRTC, camera preview, mic/cam controls, front/back camera flip
  • Live streaming (viewer) — WHEP playback via WebRTC, auto-reconnect with exponential backoff
  • Multi-party video rooms — SFU-based calls via Mediasoup + Socket.IO, up to N participants
  • Stream interactions — SSE-based floating reactions, admin chat, stream settings
  • Headless hooksusePublisher, useViewer, useVideoCall, useStreamInteraction
  • JWT config — server URLs and ICE servers can be embedded in your auth token

Installation

npm install @truncatetechnologies/streamsdk-rn

Then install the required peer dependencies:

npm install react-native-webrtc react-native-sse socket.io-client mediasoup-client

For iOS, run CocoaPods after installing:

cd ios && pod install

Setup

Call registerGlobals() once at app startup in your index.js before AppRegistry:

import { registerGlobals } from 'react-native-webrtc';
registerGlobals();

import { AppRegistry } from 'react-native';
import App from './App';
AppRegistry.registerComponent('MyApp', () => App);

Permissions

Android — add to AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

iOS — add to Info.plist:

<key>NSCameraUsageDescription</key>
<string>Camera access required for live video.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Microphone access required for live audio.</string>
<key>NSLocalNetworkUsageDescription</key>
<string>Local network access is needed for low-latency video connections.</string>

Authentication

Your backend exchanges an API key for a short-lived JWT — never put the API key in the app bundle.

import { TruncateClient } from '@truncatetechnologies/streamsdk-rn';

const res = await fetch('https://your-backend.com/sdk-token?role=publisher&streamId=my-stream');
const { token, config } = await res.json();

const client = new TruncateClient({ token, apiUrl: config.apiUrl, mediaUrl: config.mediaUrl });

See Token Server setup for a ready-made Express example.


Quick Start

Live Streaming (Publisher)

import { RTCView } from 'react-native-webrtc';
import { usePublisher } from '@truncatetechnologies/streamsdk-rn';

export default function StreamScreen({ client }) {
  const {
    streamURL, status, elapsed, micOn, camOn,
    startStream, stopStream, toggleMic, toggleCam, switchCamera,
  } = usePublisher(client, 'my-stream-123');

  return (
    <View style={{ flex: 1 }}>
      {streamURL && <RTCView streamURL={streamURL} style={{ flex: 1 }} objectFit="cover" mirror />}
      {status === 'idle' && <Button title="Go Live" onPress={startStream} />}
      {status === 'live' && (
        <>
          <Text>LIVE — {elapsed}s</Text>
          <Button title={micOn ? 'Mute' : 'Unmute'} onPress={toggleMic} />
          <Button title={camOn ? 'Cam Off' : 'Cam On'} onPress={toggleCam} />
          <Button title="Flip Camera" onPress={switchCamera} />
          <Button title="End Stream" onPress={stopStream} />
        </>
      )}
    </View>
  );
}

Live Streaming (Viewer)

import { RTCView } from 'react-native-webrtc';
import { useViewer } from '@truncatetechnologies/streamsdk-rn';

export default function WatchScreen({ client }) {
  const { streamURL, status } = useViewer(client, 'my-stream-123');

  return (
    <View style={{ flex: 1 }}>
      {streamURL
        ? <RTCView streamURL={streamURL} style={{ flex: 1 }} objectFit="cover" />
        : <Text>{status === 'waiting' ? 'Stream not started yet...' : 'Connecting...'}</Text>
      }
    </View>
  );
}

Multi-party Video Room

import { RTCView } from 'react-native-webrtc';
import { useVideoCall } from '@truncatetechnologies/streamsdk-rn';

export default function RoomScreen({ client, roomId }) {
  const {
    localStreamURL, remoteStreamURLs, peers,
    micOn, camOn, connected,
    toggleMic, toggleCam, leaveCall, sendTextMessage,
  } = useVideoCall(client, roomId, { displayName: 'Alice' });

  return (
    <View style={{ flex: 1 }}>
      <FlatList
        data={peers}
        keyExtractor={p => p.id}
        numColumns={2}
        renderItem={({ item }) => (
          remoteStreamURLs[item.id]
            ? <RTCView streamURL={remoteStreamURLs[item.id]} style={{ width: '50%', aspectRatio: 1 }} />
            : null
        )}
      />
      {localStreamURL && (
        <RTCView streamURL={localStreamURL} style={{ width: 100, height: 150, position: 'absolute', bottom: 80, right: 10 }} mirror />
      )}
      <View style={{ flexDirection: 'row', justifyContent: 'center', padding: 12 }}>
        <Button title={micOn ? 'Mute' : 'Unmute'} onPress={toggleMic} />
        <Button title={camOn ? 'Cam Off' : 'Cam On'} onPress={toggleCam} />
        <Button title="Leave" onPress={leaveCall} color="red" />
      </View>
    </View>
  );
}

API Reference

TruncateClient

new TruncateClient({ token, apiUrl, mediaUrl })

| Param | Type | Description | |---|---|---| | token | string | JWT from your token server | | apiUrl | string | API base URL (signaling, WHIP, WHEP, SSE) | | mediaUrl | string | Media server URL |


usePublisher(client, streamId)

| Return | Type | Description | |---|---|---| | streamURL | string \| null | Pass to <RTCView streamURL={...} /> | | status | string | idle \| starting \| live \| error | | elapsed | number | Seconds since going live | | micOn | boolean | Microphone enabled state | | camOn | boolean | Camera enabled state | | startStream | fn | Begin WHIP publishing | | stopStream | fn | End stream (sends WHIP DELETE) | | toggleMic | fn | Toggle microphone | | toggleCam | fn | Toggle camera | | switchCamera | fn | Flip front/back camera |


useViewer(client, streamId)

| Return | Type | Description | |---|---|---| | streamURL | string \| null | Pass to <RTCView streamURL={...} /> | | status | string | connecting \| live \| waiting \| reconnecting \| error | | muted | boolean | Current mute state | | toggleMute | fn | Toggle audio mute |

Auto-reconnects with exponential backoff (3–10 s, max 10 retries). Returns waiting when stream is offline (HTTP 404).


useVideoCall(client, roomId, options)

| Return | Type | Description | |---|---|---| | localStreamURL | string \| null | Local camera stream URL | | remoteStreamURLs | { [peerId]: string } | Remote peer stream URLs | | peers | Peer[] | Connected participants | | connected | boolean | Room connection state | | micOn / camOn | boolean | Mic/cam state | | toggleMic / toggleCam | fn | Toggle mic/cam | | leaveCall | fn | Leave room and clean up | | messages | ChatMessage[] | Chat history | | sendTextMessage(text) | fn | Send chat message |

Options: { displayName: string }


useStreamInteraction(client, streamId)

| Return | Type | Description | |---|---|---| | chatMessages | ChatMessage[] | Broadcast chat messages | | floatingReactions | Reaction[] | Active floating reactions (auto-expire after 3.5s) | | settings | object | { reactionsEnabled: boolean } | | sendReaction(emoji) | fn | Send a reaction (viewer role) | | sendChat(message) | fn | Broadcast chat (publisher role) | | updateSettings(patch) | fn | Update stream settings (publisher role) |


Links


MIT License. Copyright © Truncate Technologies.