Skip to content
Agentmart
Submit a tool

react-native-moq

Software Mansion's react-native-moq — Media over QUIC (MoQ) live streaming for React Native: sub-second-latency video/audio playback, camera/mic/screen…

Skill by software-mansion-labs

IndexedMIT★ 296
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/software-mansion-labs-react-native-moq

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

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'.

Use cases: design, frontend, data, writing

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/react-native-moq

What's inside

Skill 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
Instructions
79 lines in SKILL.md · view on GitHub

Files (5)

  • SKILL.md
  • custom-tracks.md · references/
  • imperative.md · references/
  • playback.md · references/
  • publishing.md · references/

SKILL.md (first lines)

# react-native-moq

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+.

```sh
npm install react-native-moq
cd ios && pod install
```

Optional player chrome (fullscreen modal, controls, volume slider):

```sh
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>`.

## Mental model

- A **Session** is one connection to a MoQ relay (`useSession(url)`). It does **not** auto-connect — call `session.connect()` yourself. One session serves both subscribing and publishing.
- **Subscribing:** `useBroadcasts(session, prefix)` lists live broadcasts under a path prefix → pick a `BroadcastInfo` → `useVideoPlayer` / `useAudioPlayer` → render with `<VideoView player={player}>`. Raw-media alternatives: `useAudioChunks` (encoded or PCM to JS) and `useDataMessages` (string payloads).
- **Publishing:** capture hooks produce **tracks** (`useCamera`, `useMicrophone`, `useMultiCamera`) or you generate them (`useDataTrack`, `useAudioSource`, `useVideoSource`) → `usePublisher(session).publish({ path, tracks })`. Screen sharing (`useScreenBroadcast`) is separate and out-of-process.
- Every hook has a hook-free counterpart — `create*` (returns the object plus `destroy()`) for the stateful ones, `subscribe*` (returns `start()`/`stop()`) for the subscription hooks — see [references/imperative.md](references/imperative.md).
- Objects expose reactive state (`session.state`, `publisher.state`, `player.isPlaying`, …); hooks re-render on changes. Subscribe manually with `addListener` or the `useEvent`/`useEventListener` helpers.

## Quick start — watch

```tsx
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.

## Quick start — go live

```tsx
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] });
```

## Critical rules

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.

## References

| 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, microphone, publisher lifecycle, screen broadcasting, codec queries | [references/publishing.md](references/publishing.md) |
| Data tracks & messages, audio chunks to JS, push-your-own audio (PCM) and video (frame buffers) | [references/custom-tracks.md](references/custom-tracks.md) |
| Using without React: `create*` handles, `subscribe*` functions, cleanup | [references/imperative.md](references/imperative.md) |

From software-mansion-labs/skills, MIT.

More from software-mansion-labs/skills

Compare and alternatives

    Featured in

    Signals

    Stars
    296
    Forks
    21
    Open issues
    3
    Last commit (this folder)
    Jul 29, 2026 (3 months ago)

    From GitHub (fetched Oct 24, 2026).

    Details

    License
    MIT
    First seen
    Oct 24, 2026
    Last checked
    Oct 24, 2026

    More from software-mansion-labs

    Cite this page

    react-native-moq skill. Agent Mart. https://agentmart.dev/skills/software-mansion-labs-react-native-moq (last updated 2026-10-24)