MoQ is under active development. APIs will change, but we keep backwards wire compatibility.

Skip to content

TypeScript ​

A from-scratch implementation for browsers, built on WebTransport, WebCodecs, and WebAudio. @moq/net also runs in Node, Bun, and Deno.

Packages ​

PackageDoes
@moq/netThe pub/sub layer: connections, broadcasts, tracks, groups, frames, discovery.
@moq/patternExact path patterns: grammar, matching, and set algebra. Re-exported by @moq/net and @moq/auth.
@moq/hangThe media layer: catalog types and containers.
@moq/watchSubscribe, decode, and render. <moq-watch> plus an optional UI overlay.
@moq/publishCapture, encode, and publish. <moq-publish> plus an optional UI overlay.
@moq/roomHeadless rooms: announce-derived roster, local publish, remote watch, and a chat track.
@moq/authValidate a relay's request, build its grant, and mint and verify relay JWTs.
@moq/signalsThe reactive primitives every package exposes its state through.
@moq/jsonJSON over tracks: snapshots with merge-patch deltas, or append logs.
@moq/flateOpaque payloads over tracks, optionally compressed with group-scoped DEFLATE: snapshots or append logs.
@moq/loc, @moq/msfThe IETF LOC container and MSF catalog.
@moq/boyThe MoQ Boy player element.

Web components ​

The fastest way in. No framework, no build step required:

html
<script type="module">
    import "https://esm.sh/@moq/watch/element";
    import "https://esm.sh/@moq/publish/element";
</script>

<moq-publish url="https://relay.example.com/anon" name="room/alice.hang" source="camera">
    <video muted autoplay></video>
</moq-publish>

<moq-watch url="https://relay.example.com/anon" name="room/alice.hang">
    <canvas></canvas>
</moq-watch>

With a bundler, bun add @moq/watch @moq/publish and import the same /element entrypoints (the suffix keeps tree-shaking from dropping the registration). Add /ui for the ready-made control overlays. Every attribute is also a typed, reactive JS property, and the elements expose their internal pipeline (broadcast, video, audio, signals) for apps that want more. They work in React, Vue, Solid, and plain HTML alike; @moq/signals ships React and Solid adapters for the reactive state.

JavaScript API ​

Below the elements, Watch.Player owns a headless playback pipeline, Publish.Broadcast owns a headless publisher, and @moq/net is the protocol itself. Examples: js/net/examples/ covers connecting, publishing, subscribing, and discovery.

Browser support ​

BrowserTransport
Chrome, Edge 97+WebTransport
Firefox 153+WebTransport. Earlier Firefox ships it but allows too few incoming streams, so the client falls back to WebSocket there.
WebKit (Safari, Chrome, Firefox, and Edge on iOS)WebSocket fallback. Safari 26.4 ships WebTransport, but WebKit bugs stall long sessions, so the client doesn't use it yet.
Anything elseAutomatic WebSocket fallback, with TCP's head-of-line blocking

WebCodecs support varies per codec and browser; <moq-watch-support> and <moq-publish-support> render what the current browser can do. Outside localhost the relay needs a real certificate, or the page must pin its fingerprint.

Server-side ​

@moq/net runs in Bun, Node 21+, and Deno over the WebSocket fallback with no changes (older Node needs the ws polyfill on globalThis). For real QUIC on the server, install the native @moq/web-transport polyfill. @moq/hang, @moq/watch, and @moq/publish are browser-only, so server-side media work means raw tracks plus your own encoder.

Licensed under MIT or Apache-2.0