detour-onboarding
Complete onboarding guide for developers who are new to Detour, the open-source deferred deep…
Software Mansion's react-native-moq — Media over QUIC (MoQ) live streaming for React Native: sub-second-latency video/audio playback, camera/mic/screen publishing, and realtime data tracks over a MoQ relay. MUST USE before writing, reviewing, or debugging ANY code that uses
$ npx -y skills add software-mansion-labs/skills --skill react-native-moq --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/react-native-moqContext preview
The summary Claude sees to decide when to auto-load this skill.
Software Mansion's react-native-moq — Media over QUIC (MoQ) live streaming for React Native: sub-second-latency video/audio playback, camera/mic/screen publishing, and realtime data tracks over a MoQ relay. MUST USE before writing, reviewing, or debugging ANY code that uses
name: react-native-moq description: "Software Mansion's react-native-moq — Media over QUIC (MoQ) live streaming for React Native: sub-second-latency video/audio playback, camera/mic/screen publishing, and realtime data tracks over a MoQ relay. MUST USE before writing, reviewing, or debugging ANY code that uses react-native-moq or react-native-moq-ui. Trigger on: 'react-native-moq', 'MoQ', 'Media over QUIC', 'moq relay', 'moq-kit', 'useSession', 'useBroadcasts', 'useVideoPlayer', 'useAudioPlayer', 'usePublisher', 'useCamera', 'useMultiCamera', 'useMicrophone', 'useScreenBroadcast', 'useDataTrack', 'useDataMessages', 'useAudioChunks', 'useAudioSource', 'useVideoSource', 'VideoView', 'PublisherView', 'VideoPlayerView', 'BroadcastPickerView', 'createSession', 'createPublisher', 'subscribeBroadcasts'." license: MIT
React Native bindings for Media over QUIC (MoQ): live video, audio, and data tracks with sub-second latency, published to and consumed from a MoQ relay. Built on Software Mansion's moq-kit native library.
**Requirements:** React Native New Architecture (Fabric + TurboModules), iOS 16+, Android API 30+.
npm install react-native-moq cd ios && pod install
Optional player chrome (fullscreen modal, controls, volume slider):
npm install react-native-moq-ui @react-native-vector-icons/material-icons
iOS also needs `MaterialIcons.ttf` under `UIAppFonts` in Info.plist, then `pod install` again. Skip this package if composing your own player UI on `<VideoView>`.
function Watch() {
const session = useSession('https://relay.example.com', (s) => s.connect());
const broadcasts = useBroadcasts(session, ''); // '' = all paths
return broadcasts.map((b) => <BroadcastPlayer key={b.path} broadcast={b} />);
}
function BroadcastPlayer({ broadcast }: { broadcast: BroadcastInfo }) {
const player = useVideoPlayer(broadcast, (p) => p.play());
return <VideoView player={player} style={{ width: '100%', aspectRatio: 16 / 9 }} />;
}`useVideoPlayer`/`useAudioPlayer` require a non-null broadcast — mount them in a child rendered only once one exists.
const session = useSession(url, (s) => s.connect());
const camera = useCamera();
const microphone = useMicrophone();
const publisher = usePublisher(session);
<PublisherView camera={camera} style={styles.preview} />
// when session.state === 'connected':
publisher.publish({ path: 'live/test', tracks: [camera, microphone] });1. **Errors are strings, not exceptions.** States are unions like `'connected' | 'error:...'`; check `state.startsWith('error:')`. Nothing throws on media failure. Sessions carry the message **only** in the state string (`state.slice(6)`); capture tracks and the publisher additionally expose a `lastError` field. Players have no error surface at all — watch session and publisher state instead. 2. **`publish()` requires `session.state === 'connected'`**, otherwise the publisher goes straight to `error:session is not connected`. Gate the go-live button on session state. 3. **Gate codecs with `getSupportedVideoCodecs()` / `getSupportedAudioCodecs()`.** On Android an unsupported encoder (often `h265`) makes publishing start then silently stop with no error. Default to `h264`/`opus`. 4. **Permissions are the host app's job** — request CAMERA/RECORD_AUDIO on Android, add NSCameraUsageDescription/NSMicrophoneUsageDescription on iOS. A black preview usually means a missing permission. 5. **`<VideoView>` takes no children** (the Android native view is not a ViewGroup). Render overlays as absolutely-positioned siblings. 6. **Capture hooks are refcounted device singletons** — all consumers share the physical camera/mic; `flip()` affects everyone. Use `enabled: false` to keep hardware off while mounted instead of calling hooks conditionally. 7. **Broadcast paths are relative to the subscription prefix** (broadcast `live/test` appears as `path: 'test'` under prefix `'live'`). Subscribe with `''` to see full paths. A listed broadcast that won't play (relay error `code=13` NotFound) means a path/prefix mismatch. 8. **Data tracks are not in the catalog** — publisher and subscriber must agree on the track name out of band (default `'data'`). 9. An idle iOS microphone capture holds the audio session in `playAndRecord` and can block other audio libraries (`insufficientPriority`). Disable the mic (`enabled: false`) when not publishing.
| Task | Read | | --- | --- | | Sessions, broadcast discovery, video/audio playback, `<VideoView>`, stats, track switching, events, `react-native-moq-ui` | [references/playback.md](references/playback.md) | | Camera, multi-camera,
Software Mansion's set of skills for AI-assisted React Native development.
Repo: software-mansion-labs/skills
Complete onboarding guide for developers who are new to Detour, the open-source deferred deep…
Use when the user mentions migrating deep links, switching away from Branch or AppsFlyer,…
Software Mansion's guide for migrating Expo SDK apps to Meta Quest using expo-horizon…
Software Mansion's Fishjam — hosted WebRTC platform for video, audio, and one-to-many…
Node.js / TypeScript server SDK for Fishjam — backends that create rooms, mint peer tokens,…
Fishjam platform fundamentals — domain model and auth shared by all SDKs. Covers glossary…