skills/fishjam/references/react-native-client/SKILL.md
React Native / Expo SDK for Fishjam — video/audio streaming on iOS and Android. Use when writing a React Native or Expo app that calls Fishjam, configures the Fishjam Expo plugin, sets up permissions, runs background streaming, integrates CallKit, or renders RTCView. Trigger on: '@fishjam-cloud/react-native-client', 'fishjam expo plugin', 'FishjamProvider mobile', 'useCameraPermissions', 'useMicrophonePermissions', 'useForegroundService', 'useCallKit', 'useCallKitEvent', 'useCallKitService', 'RTCView', 'RTCPIPView', 'ScreenCapturePickerView', 'startPIP', 'stopPIP', 'AudioDeviceType', 'useAudioOutput', '@fishjam-cloud/react-native-webrtc', 'fishjam react native', 'expo fishjam', 'fishjam ios', 'fishjam android', 'broadcast extension'. Re-exports @fishjam-cloud/react-client hooks plus mobile-only: permissions, foreground service, iOS broadcast extension, audio routing, CallKit, Expo config plugin.
npx skillsauth add software-mansion-labs/react-native-skills fishjam-react-native-clientInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
@fishjam-cloud/react-native-client — Fishjam's SDK for React Native / Expo apps on iOS and Android. Re-exports the web @fishjam-cloud/react-client hook surface, overrides some hooks with mobile-aware versions, and adds mobile-only APIs.
Read
../platform/SKILL.mdfirst for the domain model.Read
../react-client/SKILL.mdfor the shared hook catalog. This skill is the mobile delta — permissions, foreground service, screen-share broadcast extension, CallKit, audio routing, the Expo plugin. The hooks that work identically to the web SDK aren't re-documented here.
npm install @fishjam-cloud/react-native-client @fishjam-cloud/react-native-webrtc
# @fishjam-cloud/react-native-webrtc is a peerDependency — install it explicitly.
# Do NOT install upstream `react-native-webrtc` (the unforked package) — it will collide.
app.json (Expo):
{
"expo": {
"plugins": [
[
"@fishjam-cloud/react-native-client",
{
"android": {
"enableForegroundService": true,
"enableScreensharing": true
},
"ios": {
"enableScreensharing": true,
"broadcastExtensionTargetName": "MyAppScreenSharing",
"broadcastExtensionDisplayName": "MyApp Screen Sharing",
"appGroupContainerId": "group.com.myapp.screensharing",
"mainTargetName": "MyApp"
}
}
]
]
}
}
Then npx expo prebuild to generate native code.
import { FishjamProvider } from '@fishjam-cloud/react-native-client';
export default function App() {
return (
<FishjamProvider fishjamId={process.env.EXPO_PUBLIC_FISHJAM_ID!}>
<Room />
</FishjamProvider>
);
}
../react-client/)These hooks behave identically to the web SDK — see ../react-client/ references.
useConnection, useDataChannel, useSandbox, useUpdatePeerMetadata, useVAD, Variant, InitializeDevicesSettings.
useSandboxRoomTypedivergence. The web SDK accepts'audio_only'(underscore); the React Native SDK accepts'audio-only'(hyphen). Passing the wrong form on either platform makes the Sandbox API reject the request. (Web wire format isaudio_only; the RN hook silently sends'audio-only'and the server validation 400s.)
Same call signatures as web; internals adapted to React Native. Read ../react-client/ references for the API, then this skill's mobile-hook-overrides.md for behavioral deltas.
useCamera, useMicrophone, useScreenShare, useCustomSource, useInitializeDevices, useLivestreamStreamer, useLivestreamViewer, usePeers.
| Hook / API | Purpose | Reference |
|---|---|---|
| useCameraPermissions, useMicrophonePermissions | Query / request iOS-Android device permissions | permissions.md |
| useForegroundService | Keep audio/video/screen-share alive when the app is backgrounded on Android | foreground-service.md |
| useCallKit, useCallKitEvent, useCallKitService | iOS CallKit integration (treats Fishjam sessions as native phone calls) | callkit.md |
| useAudioOutput + AudioDeviceType | Switch audio routing (speaker / earpiece / Bluetooth) | audio-output.md |
| RTCView, RTCPIPView | Native components for rendering video tracks (in place of <video>) | rtcview.md |
| ScreenCapturePickerView + startPIP / stopPIP | Native components / functions for iOS screen picker and Picture-in-Picture | screen-sharing.md, picture-in-picture.md |
FishjamProvider differencesThe mobile provider is a thin wrapper around the React one but drops two props:
persistLastDevice — not supported on mobile (no localStorage; OS manages device selection).fishjamClient — internal-only on mobile (the SDK constructs its own with clientType: 'mobile').All other props (fishjamId, reconnect, constraints, bandwidthLimits, videoConfig, audioConfig, debug) work the same as web.
@fishjam-cloud/react-native-webrtc (the fork) — but NOT the upstream react-native-webrtc. The fork is a peerDependency of @fishjam-cloud/react-native-client, so you must add it explicitly. Installing the upstream (unforked) react-native-webrtc will collide with the fork and break the native build.app.json/app.config.ts. For bare: still register and run npx expo prebuild, or do the manual native steps (native-setup.md).useInitializeDevices. iOS in particular will silently fail device init if NSCameraUsageDescription / NSMicrophoneUsageDescription isn't declared and granted.useForegroundService solves this.broadcastExtensionTargetName + appGroupContainerId and the plugin scaffolds it during prebuild.ios.supportsPictureInPicture: true and enableVoIPBackgroundMode: true for CallKit-paired calls.| File | When to read |
|---|---|
| native-setup.md | Install + Expo plugin options (Android + iOS), bare workflow manual steps, prebuild flow. |
| permissions.md | useCameraPermissions, useMicrophonePermissions, request-before-init pattern. |
| rtcview.md | Rendering video — RTCView props (streamURL, trackId, mediaStream), RTCPIPView, mirror / styling. |
| screen-sharing.md | Android MediaProjection vs iOS Broadcast Extension; ScreenCapturePickerView; app-group pitfalls. |
| foreground-service.md | ForegroundServiceConfig, Android permissions, iOS background modes. |
| picture-in-picture.md | RTCPIPView, startPIP, stopPIP, plugin flags. |
| callkit.md | useCallKit, useCallKitEvent, useCallKitService, CallKitConfig, CallKitAction. |
| audio-output.md | useAudioOutput, AudioDeviceType, switching speaker / earpiece / Bluetooth. |
| mobile-hook-overrides.md | Per-hook behavioral deltas vs the web SDK. |
| example-projects.md | Runnable apps in the fishjam-cloud/examples repo under mobile-react-native/. |
development
Use when the user mentions migrating deep links, switching away from Branch or AppsFlyer, replacing their deep linking SDK, setting up Detour deep linking for the first time, or asks how Branch/AppsFlyer concepts map to Detour. Covers the complete migration end to end - Detour Dashboard configuration, Universal Links and App Links setup, SDK swap with code examples, and analytics migration. Works across Android, iOS, React Native, and Flutter.
development
Complete onboarding guide for developers who are new to Detour, the open-source deferred deep linking SDK by Software Mansion. Use this skill whenever a user asks what Detour is, how to get started with Detour, how to set up deep linking with Detour, how to install the Detour SDK, how to configure the Detour dashboard, or how deferred deep linking works. Also use it when the user has no prior deep linking setup and wants to add deep links to their app. Covers everything from zero to production: account setup, dashboard configuration, Universal Links and App Links, platform SDK integration for React Native, iOS, Android, and Flutter, analytics, and architecture.
tools
Browser-only React SDK for Fishjam — joining rooms, capturing camera/microphone/screen, displaying peers, and acting as a livestream streamer or viewer in a React web app. Use whenever the user is writing a React app in a browser that calls Fishjam APIs, sets up FishjamProvider, or uses any Fishjam React hook. Trigger on: '@fishjam-cloud/react-client', 'FishjamProvider', 'useConnection', 'useCamera', 'useMicrophone', 'useScreenShare', 'usePeers', 'useDataChannel', 'useVAD', 'useLivestreamStreamer', 'useLivestreamViewer', 'useCustomSource', 'useInitializeDevices', 'useUpdatePeerMetadata', 'useSandbox', 'PeerWithTracks', 'joinRoom', 'peerToken', 'fishjamId', 'fishjam react', '@fishjam-cloud/ts-client', 'FishjamClient ts-client'. Covers the provider, the full hook catalog, simulcast configuration, custom sources, data channels, VAD, livestream WHEP playback, device persistence, and reconnection. Briefly notes when to drop down to @fishjam-cloud/ts-client for non-React or worker contexts.
tools
Python server SDK for Fishjam — backends that create rooms, mint peer tokens, receive server notifications, and run voice agents. Use when writing a Python backend (FastAPI, Flask, Starlette, aiohttp) that talks to Fishjam, decorates a notification handler, decodes a Fishjam webhook, or builds an AI voice agent in Python. Trigger on: 'fishjam-server-sdk', 'pip install fishjam-server-sdk', 'from fishjam import', 'fishjam.FishjamClient', 'FishjamNotifier', 'on_server_notification', 'receive_binary', 'fishjam Agent', 'AgentSession', 'PeerOptions', 'RoomOptions', 'AgentOptions', 'AgentOutputOptions', 'OutgoingAudioTrackOptions', 'create_room', 'create_peer', 'create_agent', 'create_vapi_agent', 'create_livestream_streamer_token', 'create_moq_token', 'subscribe_peer', 'fastapi fishjam', 'flask fishjam', 'fishjam python', 'gemini fishjam python'. Python 3.10+. The REST client is synchronous; notifier and agent are async.