MoQ Boy Escaped the Browser: Building a Native Mobile MoQ Client with moq-kit

by Jakub Perżyło • Jun 22, 2026 • 6 min read

MoQ Boy Escaped the Browser: Building a Native Mobile MoQ Client with moq-kit cover

moq-kit is a native mobile Media over QUIC client library. To show what it can do, we took MoQ Boy – a Game Boy-style demo that’s been running in the browser – and moved it into a native iOS app.

The demo has an emulator running somewhere, audio and video flowing out of it, and clients competing over whose controls take effect. It is playful, small enough to understand, and practical enough to showcase what MoQ has to offer.

Now the boy has escaped the browser. The same demo is running in a native MoQ client – moq-kit – built on Media over QUIC, with audio/video playback, tunable latency, and game controls published back as a MoQ track. It is still a demo, but it starts to look much closer to the kind of integration real media apps need.

What is Media over QUIC (MoQ)?

Media over QUIC is a way to move live media and media-adjacent data using a publish/subscribe model. A publisher exposes streams of content, a subscriber asks for what it needs, and a relay sits in the middle to make that exchange scalable.

That is the part worth keeping in mind for this article. MoQ is not a codec, not a player, and not a magic replacement for every media protocol. It is a way to build live media systems where the application can make explicit choices about what should flow, when it should flow, and how much latency it is willing to trade for freshness or continuity.

The relay is where MoQ becomes deliberately boring. It does not need to understand Game Boy emulation, player rules, room state, or why anyone is fighting over the A button. Think of it less like the director of a sitcom and more like the studio infrastructure: pick the stage, point the cameras, route the feeds. Casting Jennifer Aniston for another episode of Friends is application logic.

That boring role is exactly what makes it useful for scale. One person can watch the demo, the emulator keeps running, and the relay forwards the media to that one client. Nobody watches, and the emulator can save its extremely fictional batteries for later. Ten thousand people join, because apparently a random Game Boy session is the most interesting thing on the planet for the next five minutes, and the relay is the piece that lets the same published media scale out without every viewer connecting directly to the emulator.

At this point the RFC enjoyers will say that WebRTC already exists. Sure. Everybody loves developing WebRTC applications, right up until the moment they have to debug negotiation, ICE, SFU behavior, browser differences, and the pile of “almost standard” details between the happy-path demo and production. HLS exists too, of course. I would say more, but I am still waiting for my player to buffer ten seconds of media. Jokes aside, both protocols earned their place. WebRTC is the default answer for real-time calls, and HLS/DASH are the default answer for large-scale playback. The interesting question is whether we can take useful parts of both worlds: low-latency, application-shaped interaction on one side, and relay/CDN-style distribution on the other.

Building a Native MoQ Client with moq-kit

moq-kit is our native mobile client MoQ library. At Software Mansion, we spend a lot of time close to native mobile and real-time media, so MoQ is interesting to us exactly at this boundary: where protocol experiments need to become app integrations.

For this demo, moq-kit connects to https://cdn.moq.dev/demo, lists the available games, lets you select a cartridge, and enjoy the time like it is 1989 again. It has the same core functionality as the JavaScript libraries: play the audio/video stream, tune latency, and publish controls back into the session.

The point is not that the web demo disappeared. The web version is still the fastest way to understand the idea. The point is that the same MoQ application model can now cross into a native media stack.

That matters because native is where a lot of real media products eventually have to live. A demo in the browser is great for reach, iteration, and proving the protocol shape. A native app has to deal with the parts users do not think about until they break: playback surfaces, audio interruptions, app lifecycle, input latency, device performance, and the way media behavior fits into the rest of the product.

Why Not Just Use a WebView?

The obvious question is: why not just use the web version in a WebView?

For a demo, that is a fair answer. WebView is great when you want to prove that something works quickly. But at some point the media layer needs to stop being a page embedded inside the app and start being part of the app itself.

That is the reason for moq-kit. A native MoQ client can feed media directly into native rendering, native audio, native controls, native telemetry, native state management, and whatever custom pipeline the app already has. You do not need to build a bridge around a WebView just to move frames, controls, latency state, track selection, or diagnostics back into the real application.

The important part is customization. Adjustable latency is useful, but it is not the headline. The headline is that MoQ stops being trapped behind a browser boundary. If your app wants to use a custom renderer, combine playback with native gestures, publish app-specific controls, connect playback state to observability, experiment with different buffering policies, or plug MoQ into a media workflow that does not look like a standard player, native gives you that surface.

This matters because MoQ itself is application-shaped. The interesting parts are not only “play this URL.” They are decisions like which tracks should exist, which ones should be subscribed to, which ones should be produced only on demand, and what the client should publish back. Those decisions are easier to express when MoQ is integrated directly into the app instead of mediated through a WebView.

You can absolutely watch a translated stream in a WebView. You can also put an HLS player in a WebView. That does not mean every serious media app wants its playback stack to live there. Native is not about making the demo possible. Native is about making the demo composable with the rest of the product.

Try It

moq-kit is available on GitHub at software-mansion-labs/moq-kit. The MoQ Boy example is part of the iOS demo in examples/ios, as an Xcode project.

Run the example, connect to https://cdn.moq.dev/demo, pick one of the available cartridges, and try the same flow as the JavaScript libraries: watch the stream, adjust latency, and send controls back.

Summary

MoQ Boy is still a demo, but moving it into a native app changes what the demo proves. It is no longer only a browser example of MoQ playback. It shows a native MoQ client discovering a session, playing media, tuning latency, and publishing controls back into the same application model.

moq-kit is our step toward making that pattern available to native mobile apps. If you are building a standard VOD player, HLS is still probably the right answer. If you are building a normal video call, WebRTC still earns its place. But if your media app needs custom playback behavior, application-specific tracks, direct native integration, or demand-driven media, MoQ starts to become interesting.

Try the demo, break it, and tell us what a native MoQ client library needs before this kind of thing stops feeling like a prototype.