Software Mansion's moq-kit — native Swift (iOS) and Kotlin (Android) SDKs for Media over QUIC (moq-lite) live streaming: sub-second-latency playback, camera/microphone/screen publishing, and…

Apache-2.0Auto-check passedMobile

Install Moq Kit

skills CLI
$ npx skills add software-mansion-labs/skills --skill moq-kit -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install software-mansion-labs/skills moq-kit --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/software-mansion-labs/skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/moq-kit .claude/skills/moq-kit && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
moq-kit
GitHub stars
291
Token cost
~5k tokens
SKILL.md length
1,965 words
Files
9 (incl. references)
Skills in repo
20
Repo updated
First seen
Licence
Apache-2.0

At a glance

Software Mansion's moq-kit — native Swift (iOS) and Kotlin (Android) SDKs for Media over QUIC (moq-lite) live streaming: sub-second-latency playback, camera/microphone/screen publishing, and…

  • Works in 11 steps: Sessions, publishers, and players are… → Media track names are local labels,… → publisher.start() does not start… → …
  • Media over QUIC
  • SKILL.md covers Platform detection, Mental model, Quick start — watch and Quick start — go live, plus 6 more sections
  • Calls mise; reaches github.com

What it does

Moq Kit is an agent skill from software-mansion-labs/skills. Software Mansion's moq-kit — native Swift (iOS) and Kotlin (Android) SDKs for Media over QUIC (moq-lite) live streaming: sub-second-latency playback, camera/microphone/screen publishing, and realtime data tracks over a MoQ relay. MUST USE before writing, reviewing, or debugging ANY code that imports MoQKit (Swift) or com.swmansion.moqkit (Kotlin); for React Native apps use the react-native-moq skill instead. Trigger on: 'moq-kit', 'MoQKit', 'Media over QUIC', 'moq-lite', 'MoQ relay', 'moq-ffi'…

Its SKILL.md is about 5k tokens, which your agent loads only when the skill is triggered. The skill folder holds 9 other files, including reference files (for example `references/data-tracks-android.md`, `references/data-tracks-ios.md` and `references/playback-android.md`).

It sits in Mobile, covering Android development, iOS development and Cross-platform mobile apps. It works with Kotlin, iOS, React Native and Android. The repository describes itself as: Software Mansion's set of skills for AI-assisted React Native development. The licence is Apache-2.0.

When your agent uses it

  • Media over QUIC
  • BroadcastSubscription
  • DataTrackEmitter
  • MicrophoneCapture

Example prompts

  • “moq-kit”
  • “MoQKit”
  • “Media over QUIC”
  • “/moq-kit”

Workflow steps

11 steps, taken from the first numbered list in SKILL.md.

  1. Sessions, publishers, and players are single-use. A Session connects once (alreadyConnected/IllegalStateException on reuse); after close()…
  2. Media track names are local labels, catalog names are muxer-generated. The name: passed to addVideoTrack/addAudioTrack (defaults…
  3. publisher.start() does not start capture. Start CameraCapture/MicrophoneCapture/etc. yourself, in this order: start captures → add tracks…
  4. Gate codecs before use. VideoEncoderConfig.supportedCodecs() / AudioEncoderConfig.supportedCodecs() / .isSupported on the publish side…
  5. Player startup events are not replayed. Subscribe before play(): iOS player.subscribeEvents { ... } (and retain the returned subscription…
  6. Permissions and audio sessions are the app's job. iOS: NSCameraUsageDescription, NSMicrophoneUsageDescription…
  7. Own your references and clean up. iOS: keep strong refs to Session, BroadcastSubscription, Publisher, DataTrackEmitter, Player, and every…
  8. iOS Player is @MainActor — construct and drive it on the main actor. iOS Publisher.stop() flushes encoders synchronously — call it off the…
  9. When one session both publishes and subscribes the same prefix, it sees its own broadcast — filter it out, remembering reported paths are…
  10. Latency is tunable live: targetBuffering defaults to 100 ms; player.updateTargetLatency(_:) adjusts during playback. A second consumer of…
  11. Custom sources must share the publisher's clock domain. A Publisher stamps all of its tracks against one epoch, set by the first frame of…

What it can do on your machine

Read from SKILL.md and the folder at commit e3f00cd. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • mise

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • github.com

    Also links to:

    • mise.jdx.dev

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Moq Kit loads about 5k tokens when it runs, and up to ~13k if it reads all its reference files. Until then it costs about 190 tokens; SKILL.md has 1,965 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~190
When it runs · the whole SKILL.md, loaded when a task matches
~5k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~13k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from software-mansion-labs/skills at commit e3f00cd, republished under its Apache-2.0 licence (© software-mansion-labs). 1,965 words, ~4,958 tokens.

Download SKILL.mdSave it as .claude/skills/moq-kit/SKILL.md (or your agent's skills folder). This skill also uses 8 other files; get the full folder from GitHub.
name
moq-kit
description
Software Mansion's moq-kit — native Swift (iOS) and Kotlin (Android) SDKs for Media over QUIC (moq-lite) live streaming: sub-second-latency playback, camera/microphone/screen publishing, and realtime data tracks over a MoQ relay. MUST USE before writing, reviewing, or debugging ANY code that imports MoQKit (Swift) or com.swmansion.moqkit (Kotlin); for React Native apps use the react-native-moq skill instead. Trigger on: 'moq-kit', 'MoQKit', 'Media over QUIC', 'moq-lite', 'MoQ relay', 'moq-ffi', 'BroadcastSubscription', 'DataTrackEmitter', 'CameraCapture', 'MicrophoneCapture', 'MultiCameraCapture', 'ScreenCapture', 'TrackSubscription', 'AudioDataStream', 'MoQReplayKitBroadcastSampleHandler', or a Session/Player/Publisher/Catalog from moq-kit.
license
Apache-2.0

moq-kit

Native Swift and Kotlin SDKs for Media over QUIC live streaming: connect to a relay, discover broadcasts, play catalog-described streams with sub-second latency, publish camera/microphone/screen tracks, and exchange raw data tracks. Wraps the UniFFI bindings generated from moq-ffi (Luke Curley's moq-dev/moq); targets the moq-lite protocol, not the IETF moq-transport draft.

Requirements: iOS 16+ / macOS 13+ (Xcode 16+ to build) / Android minSdk 29, compileSdk 35. A moq-lite relay to connect to. The references cover iOS and Android; macOS is declared by the Swift package but untested here.

moq-kit is an active preview: public APIs, packaging, and codec coverage can still change between releases. Pin an exact version and check signatures against the installed artifact rather than assuming a shape.

Install — iOS (SPM):

swift
.package(url: "https://github.com/software-mansion-labs/moq-kit", exact: "<latest release>")
// product: .product(name: "MoQKit", package: "moq-kit")

Install — Android (Maven Central):

kotlin
dependencies { implementation("com.swmansion.moqkit:moqkit:<latest release>") }

Fill in <latest release> from https://github.com/software-mansion-labs/moq-kit/releases. Both pins are exact on purpose — loosen the SPM one (.upToNextMinor(from:)) only if you mean to track preview releases as they land.

Platform detection

Reference files are split per platform — read only the ones for the project at hand:

  • Package.swift, *.xcodeproj, or a Podfile → the *-ios.md references (Swift).
  • build.gradle/build.gradle.kts with com.swmansion.moqkit → the *-android.md references (Kotlin).
  • Cross-platform work (feature parity, bindings on top of both SDKs) → read both; the APIs are deliberately kept equivalent.

Mental model

  • A Session owns one QUIC connection to a relay and serves both subscribing and publishing. connect() once; a session is one-shot — after close() (or a connection error) create a new Session. Swift: actor, connect() async throws. Kotlin: optionally takes a parentScope (defaults to an internal IO scope; pass viewModelScope/lifecycleScope so cancelling it tears the session down); connect() is the only suspend call.
  • Subscribing: session.subscribe(prefix:) → stream of Broadcast → broadcast.catalogs() → pick playable tracks → Player(catalog:videoTrackName:audioTrackName:targetBuffering:) → play(). Rendering is platform-specific: iOS adds player.videoLayer (an AVSampleBufferDisplayLayer) to the view hierarchy; Android calls player.setSurface(surface) with a Surface you own.
  • Publishing: create capture sources (CameraCapture, MicrophoneCapture, MultiCameraCapture, ScreenCapture) and start them yourself → Publisher() + addVideoTrack/addAudioTrack/addDataTrack → session.publish(path, publisher) → publisher.start(). A publisher is single-use; add all tracks before start().
  • Data tracks (DataTrackEmitter → addDataTrack; consume with broadcast.subscribeTrack(name:)) bypass the media catalog — publisher and subscriber agree on the track name out of band.
  • Everything is observable: session.state, publisher.state/events, player events/stats. Kotlin uses StateFlow/SharedFlow/cold Flow; Swift uses AsyncStream for session/publisher state and diagnostics, but callback subscriptions (subscribeEvents/subscribeStats) for player events/stats.

Quick start — watch

iOS:

swift
let session = Session(url: "http://localhost:4443/anon")
try await session.connect()
let subscription = try await session.subscribe(prefix: "live")
for await broadcast in subscription.broadcasts {
    for await catalog in broadcast.catalogs() {
        let video = catalog.playableVideoTracks.first?.name
        let audio = catalog.playableAudioTracks.first?.name
        guard video != nil || audio != nil else { continue }
        let player = try await MainActor.run {
            try Player(catalog: catalog, videoTrackName: video, audioTrackName: audio)
        }
        try await player.play() // render via player.videoLayer — see playback-ios.md
    }
}

Android:

kotlin
scope.launch {
    val session = Session(url = "http://localhost:4443/anon", parentScope = scope)
    session.connect()
    session.subscribe(prefix = "live").broadcasts.collect { broadcast ->
        broadcast.catalogs().collect { catalog ->
            val video = catalog.playableVideoTracks.firstOrNull()?.name
            val audio = catalog.playableAudioTracks.firstOrNull()?.name
            if (video == null && audio == null) return@collect
            val player = Player(catalog, video, audio, parentScope = scope)
            player.setSurface(surfaceView.holder.surface)
            player.play()
        }
    }
}

Minimal on purpose: the nested loops handle one broadcast at a time — spawn a Task/launch per broadcast in real code — and each catalog update should tear down the previous player before creating the new one (players hold native handles).

Quick start — go live

Same four steps on both platforms, and the order is load-bearing (rule 3):

iOS:

swift
try await camera.start()                                   // 1. captures — publisher.start() won't do this
let publisher = try Publisher()                            // 2. every track before start()
publisher.addVideoTrack(name: "camera", source: camera, config: VideoEncoderConfig())
try await session.publish(path: "live/ios", publisher: publisher)  // 3. register
try await publisher.start()                                // 4. go live

Android:

kotlin
camera.start(context, lifecycleOwner)
val publisher = Publisher()
publisher.addVideoTrack(name = "camera", source = camera, config = VideoEncoderConfig())
session.publish(path = "live/android", publisher = publisher)
publisher.start()

Captures, previews, encoder configs, and permissions are in the publishing references.

Shared concepts (both platforms)

  • Catalogs: broadcast.catalogs() streams catalog updates — each element replaces the previous; the stream ending means the broadcast went away (mark it offline). It often ends by throwing rather than completing — a producer that disappears surfaces as MoqException$Mux: json: remote error: code=… out of collect, so handle the exception and the clean completion identically (both demo apps and react-native-moq do). Always select from playableVideoTracks / playableAudioTracks (device-filtered on Android and for iOS audio; iOS video playability is codec-family recognition only), not the raw lists; per-track isPlayable/unsupportedReason explain exclusions (they live on the concrete VideoTrackInfo/AudioTrackInfo, not the base TrackInfo). Video codec strings: "avc1", "hev1", "av01"; audio: "mp4a.40.2"/"aac" (Android-published tracks advertise "aac"), "opus". AV1 is playback-only — neither platform publishes it, and Apple-side decode is iPhone 15 Pro-class hardware, not a general capability.
  • Broadcast paths are prefix-relative: subscribing with prefix "live" reports broadcast live/game as path: "game" — subscribe with "" to see full paths.
  • Three observation channels on Player — don't mix them up: events (lifecycle milestones — player.init, playback.start, track.ready, track.switch, track.stall.start, rebuffer.end, decode.error — wire values; Kotlin matches the PlayerEventName enum; not replayed), stats (PlaybackStats at ~1 s cadence — latency, fps, bitrates, StallStats, timeToFirst, buffer depths, drops, switches), and diagnostics (typed per-frame PipelineEvent — frameDropped with DropStage/DropReason, stallStarted, latencySample, … — bounded at 256 drop-oldest — Android hands every caller the same shared flow — and never backpressures playback; for logging/telemetry only).
  • Publisher states: Idle / Publishing / Stopped / Error(message) — but Android never actually enters Error, and it does not react to the session dying either: an Android publisher sits in Publishing indefinitely after its session is gone, so the session's own state is the only signal that the broadcast stopped. Wire failure UI to events: TrackStarted / TrackStopped / a per-track error (Kotlin TrackError(name, message), Swift .error(name, message)); per-track PublishedTrack.state (Idle / Starting / Active / Stopped) with PublishedTrack.stop() to end one track. session.unpublish(path) calls publisher.stop().
  • TrackDelivery for raw track subscription: monotonic (default) skips late groups — right for newest-value-wins live state; arrival delivers every group in order — right for chat and anything lossless.

Critical rules

  1. Sessions, publishers, and players are single-use. A Session connects once (alreadyConnected/IllegalStateException on reuse); after close() make a new one. A stopped Publisher cannot be restarted. Never restart a torn-down Player on either platform — create a fresh one.
  2. Media track names are local labels, catalog names are muxer-generated. The name: passed to addVideoTrack/addAudioTrack (defaults "video"/"audio") only labels PublishedTrack and publisher events; subscribers must discover real track names from Catalog.videoTracks/audioTracks. Exception: data tracks — addDataTrack(name:) (default "data") IS the name subscribers pass to subscribeTrack(name:).
  3. publisher.start() does not start capture. Start CameraCapture/MicrophoneCapture/etc. yourself, in this order: start captures → add tracks → session.publish(path, publisher) → publisher.start().
  4. Gate codecs before use. VideoEncoderConfig.supportedCodecs() / AudioEncoderConfig.supportedCodecs() / .isSupported on the publish side; catalog.playableVideoTracks / playableAudioTracks / per-track isPlayable on the playback side. Unsupported configs throw (SessionError.unsupportedCodec / UnsupportedCodecException). H.264 + AAC/Opus are the best-tested paths; default to H.264. Opus wants 48 kHz — on Android keep MicrophoneCapture(sampleRate = …) equal to the encoder config; iOS has no mic rate knob and resamples internally.
  5. Player startup events are not replayed. Subscribe before play(): iOS player.subscribeEvents { ... } (and retain the returned subscription — it cancels on deinit); Android collect player.events with CoroutineStart.UNDISPATCHED. On both platforms player.init fires during construction and can never be observed — the rule protects track.ready/playback.start.
  6. Permissions and audio sessions are the app's job. iOS: NSCameraUsageDescription, NSMicrophoneUsageDescription, NSLocalNetworkUsageDescription (local relays), and configure AVAudioSession yourself (.playAndRecord to publish, .playback to watch) — MicrophoneCapture will not. Android: declare + request CAMERA/RECORD_AUDIO (MicrophoneCapture.start() silently no-ops without it), INTERNET, and the MediaProjection foreground-service setup for screen capture.
  7. Own your references and clean up. iOS: keep strong refs to Session, BroadcastSubscription, Publisher, DataTrackEmitter, Player, and every event/stats subscription; hold the Task handles that drive for await loops (the AsyncStreams are single-consumer, too). Android: nearly everything is AutoCloseable and holds ref-counted native handles — close() each Broadcast, BroadcastSubscription, TrackSubscription, MediaTrack, AudioDataStream, and Player (leaking one keeps the broadcast alive). broadcasts, objects, frames, and audio flows allow a single collector.
  8. iOS Player is @MainActor — construct and drive it on the main actor. iOS Publisher.stop() flushes encoders synchronously — call it off the main thread (Task.detached; note Publisher isn't Sendable, so under strict Swift 6 concurrency this needs nonisolated(unsafe) or a Swift 5-mode target).
  9. When one session both publishes and subscribes the same prefix, it sees its own broadcast — filter it out, remembering reported paths are prefix-relative: compare against your publish path with the subscribe prefix stripped. Two Sessions in one process (one publishing, one subscribing) is also supported — and since sessions are one-shot, separate ones keep a transport failure or teardown on the publish side from taking playback down with it.
  10. Latency is tunable live: targetBuffering defaults to 100 ms; player.updateTargetLatency(_:) adjusts during playback. A second consumer of the same media track (another Player, an AudioDataStream) reuses the first subscriber's upstream buffering — it can't independently lower it.
  11. Custom sources must share the publisher's clock domain. A Publisher stamps all of its tracks against one epoch, set by the first frame of any track, so a source emitting its own zero-based timeline drifts against the mic or leaves video scheduled far in the future. iOS: PTS on the host clock (CMClockGetTime(CMClockGetHostTimeClock())) — the domain AVFoundation capture already uses. Android: SystemClock.elapsedRealtimeNanos() / 1_000 for PCM (what MicrophoneCapture uses) and the same clock behind the encoder surface's presentation timestamps.
Show full SKILL.md (644 more words)Show less

Symptom → cause

SymptomLikely cause
No broadcasts ever arriveRelay URL missing the namespace path (/anon locally) — the relay answers NotFound (code=13) and nothing surfaces; or subscribe() ran before the session reached connected
Publishing "works" but subscribers get no mediaCaptures were never started — publisher.start() does not start them (rule 3)
No microphone audioiOS: AVAudioSession isn't on a record-capable category. Android: RECORD_AUDIO is missing and MicrophoneCapture.start() no-ops silently — no error either way
Android: audio plays, video is blackNo surface set, or a stale one after surfaceDestroyed — null it there and only re-apply a surface that isValid
iOS: audio plays, video is blackplayer.videoLayer was never added to a layer hierarchy or never sized — nothing renders until it's in the tree and play() has run
track.ready / playback.start never fireSubscribed after play(), or (iOS) the returned PlayerEventSubscription wasn't retained
Data-track sends disappearSent before publisher.start() or after stop() — dropped silently on both platforms; gate sends on publisher state
Nothing recovers after a network blipSessions are one-shot; on Android a Closed you didn't ask for is the failure signal. Build a new Session — but log Error(message) if you see it, it carries the only description of what went wrong
A remote error carries a bare code=NCodes are moq_net::Error discriminants: 13 NotFound, 24 Dropped "producer dropped without finishing", 25 Closed, 26 Lagged; full list in moq-net's error.rs (vendor/moq/rs/moq-net/src/error.rs in a moq-kit checkout)
iOS: UI hitches when going off-airPublisher.stop() flushes encoders synchronously — call it off the main thread
A publisher's own broadcast shows up in its subscriber listSame session publishing and subscribing the same prefix (rule 9) — filter by prefix-relative path
Custom source: A/V drifts apart, or video freezes while audio keeps playingFrame timestamps aren't in the same clock domain as the publisher's other tracks (rule 11)
Android: play() throws IllegalArgumentExceptionIt's an UnsupportedCodecException (a subclass) for an undecodable selected track — catch that first
Android: screen capture starts, then diesThe mediaProjection foreground service wasn't running yet, or was started outside the consent-result callback (Android 14+ rejects that)
Device or emulator can't reach a local relaylocalhost is the device itself — use 10.0.2.2 from the Android emulator, the host's LAN IP from physical devices

Debugging

Relay, subscription, and publish failures usually surface in the native transport log before they show up as state. Raise the level before touching any other API:

swift
KitLogger.setNativeLogLevel("debug")   // "error"/"warn"/"info"/"debug"/"trace"; only the first call takes effect
kotlin
NativeLogging.setLogLevel("debug")     // same levels; invalid values are ignored with a warning

Android native logs land in logcat under the tag MoQNative, but only when the native library was built with the android-logcat cargo feature (moq-ffi → moq-native → tracing-android); without it the tracing subscriber writes to stderr, which Android discards. A successful setLogLevel call with no MoQNative lines afterwards means the feature is off in the artifact you are using — fall back to session/publisher state and player events there.

iOS also logs through os_log under subsystem com.swmansion.MoQKit (categories session, transport, catalog, media, player, publish) — filter Console.app on it. Per-frame drop/stall detail is on the player's diagnostics channel, not in these logs.

Testing against a relay

From a moq-kit checkout (needs Rust + mise): mise run relay:run starts a local moq-lite relay at http://localhost:4443/anon; mise run media:to-fmp4 converts a video to CMAF fMP4 and mise run stream:file --input file.mp4 loops it into the relay as a broadcast. Use the machine's LAN IP instead of localhost from physical devices, and 10.0.2.2 from the Android emulator (the emulator's fixed alias for the host's loopback — its own localhost is itself; the iOS simulator shares the host's). The relay URL must include the namespace path (/anon locally) — with it wrong or missing, broadcasts simply never appear (relay NotFound, code=13). The demo apps (examples/ios/demo/MoQDemo, examples/android/demo/MoQDemo) are the canonical integration references.

References

TaskiOS (Swift)Android (Kotlin)
Playback: session, discovery, Player, rendering, events/stats wiringreferences/playback-ios.mdreferences/playback-android.md
Publishing: camera, multi-camera, microphone, previews, encoder configs, permissionsreferences/publishing-ios.mdreferences/publishing-android.md
Screen sharingreferences/screen-capture-ios.mdreferences/screen-capture-android.md
Data tracks, raw compressed media (MediaTrack), decoded PCM (AudioDataStream)references/data-tracks-ios.mdreferences/data-tracks-android.md

© software-mansion-labs, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 8 other files (references) in skills/moq-kit of software-mansion-labs/skills.

  • SKILL.md
  • references/data-tracks-android.md
  • references/data-tracks-ios.md
  • references/playback-android.md
  • references/playback-ios.md
  • references/publishing-android.md
  • references/publishing-ios.md
  • references/screen-capture-android.md
  • references/screen-capture-ios.md

Open the folder on GitHubat commit e3f00cd

Compare with similar skills

Moq Kit next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Moq Kit compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Moq Kit this skillsoftware-mansion-labs/skills291—~5kAutomated safety check: PassApache-2.0
Expo Brownfield Integrationmweinbach/agent-coworker1562 repos~900Automated safety check: NotesCustom licence
Simulator Audio E2Ehyochan/react-native-nitro-sound961—~1.1kAutomated safety check: PassMIT
Expo Brownfieldexpo/skills2.7k—~1.4kAutomated safety check: PassMIT
Mobile Apps Createforcedotcom/sf-skills1.1k—~1.4kAutomated safety check: PassApache-2.0
Expo UIarcboxlabs/linkcode155—~1.2kAutomated safety check: PassMIT

Similar skills

  • Expo Brownfield Integration

    mweinbach/agent-coworker

    Helps add Expo and React Native to an existing native iOS or Android app, and choose between a prebuilt AAR or XCFramework and a fully integrated build.

    156 GitHub starsUsed in 2 repos~900 tokens
    MobileAuto-check: notes
  • Simulator Audio E2E

    hyochan/react-native-nitro-sound

    Build and run repeatable react-native-nitro-sound recorder/player regression tests on an iOS Simulator or Android emulator, with explicit virtual-device selection, microphone permission, Maestro…

    961 GitHub stars~1.1k tokensUpdated 10 days ago
    MobileAuto-check passed
  • Expo Brownfield

    expo/skills

    Official

    Integrate Expo and React Native into an existing native iOS or Android app.

    2.7k GitHub stars~1.4k tokensUpdated 3 days ago
    MobileAuto-check passed
  • Mobile Apps Create

    forcedotcom/sf-skills

    The entry point for building any Salesforce native mobile app on iOS or Android.

    1.1k GitHub stars~1.4k tokensUpdated today
    MobileAuto-check passed
  • Expo UI

    arcboxlabs/linkcode

    Framework (OSS). An agent skill from arcboxlabs/linkcode.

    155 GitHub stars~1.2k tokensUpdated 12 days ago
    MobileAuto-check passed
  • Ksafe

    ioannisa/KSafe

    Required before any reply that touches KSafe (by ksafe(...), ksafe.get/put, :ksafe-compose, :ksafe-biometrics), even a 'can KSafe do X?' question or a one-line change that looks like plain Kotlin.

    338 GitHub stars~17k tokensUpdated 6 days ago
    MobileAuto-check passed

More from software-mansion-labs/skills

All 20 skills in this repo
  • Detour Onboarding

    software-mansion-labs/skills

    Complete onboarding guide for developers who are new to Detour, the open-source deferred deep linking SDK by Software Mansion.

    291 GitHub stars~2.8k tokensUpdated 12 days ago
    Auto-check passed
  • Typegpu

    software-mansion-labs/skills

    TypeGPU is type-safe WebGPU in TypeScript. An agent skill from software-mansion-labs/skills.

    291 GitHub starsUsed in 2 repos~5.6k tokens
    Auto-check passed
  • Enable Worklets Bundle Mode

    software-mansion-labs/skills

    Enable react-native-worklets Bundle Mode (imports inside worklets, third party libraries on worklet runtimes) in an Expo, RN CLI or brownfield React Native app, including the mandatory…

    291 GitHub stars~4k tokensUpdated 12 days ago
    Auto-check passed
  • React Native Moq

    software-mansion-labs/skills

    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…

    291 GitHub stars~1.6k tokensUpdated 12 days ago
    Auto-check passed
  • Expo Horizon

    software-mansion-labs/skills

    Software Mansion's guide for migrating Expo SDK apps to Meta Quest using expo-horizon packages.

    291 GitHub stars~2.8k tokensUpdated 12 days ago
    Auto-check passed
  • Fishjam JS Server SDK

    software-mansion-labs/skills

    Node.js / TypeScript server SDK for Fishjam — backends that create rooms, mint peer tokens, listen to server notifications, and run agents.

    291 GitHub stars~1.4k tokensUpdated 12 days ago
    Auto-check passed

Categories

Questions about Moq Kit

What does Moq Kit do?

Software Mansion's moq-kit — native Swift (iOS) and Kotlin (Android) SDKs for Media over QUIC (moq-lite) live streaming: sub-second-latency playback, camera/microphone/screen publishing, and…. Moq Kit is an agent skill from software-mansion-labs/skills. Software Mansion's moq-kit — native Swift (iOS) and Kotlin (Android) SDKs for Media over QUIC (moq-lite) live streaming: sub-second-latency playback, camera/microphone/screen publishing, and realtime data tracks over a MoQ relay.

When should I use Moq Kit?

Moq Kit fits situations like: media over QUIC; broadcastSubscription; dataTrackEmitter; microphoneCapture.

How do I install Moq Kit in Claude Code?

Run `npx skills add software-mansion-labs/skills --skill moq-kit -a claude-code`. Or copy the skill folder (skills/moq-kit in software-mansion-labs/skills) into .claude/skills/moq-kit in your project. Claude Code loads it when a task matches its description.

How do I install Moq Kit in Codex?

Run `npx skills add software-mansion-labs/skills --skill moq-kit -a codex`. Or copy the skill folder (skills/moq-kit in software-mansion-labs/skills) into .agents/skills/moq-kit in your project. Codex loads it when a task matches its description.

Can I use Moq Kit in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add software-mansion-labs/skills --skill moq-kit -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/moq-kit, .gemini/skills/moq-kit, .github/skills/moq-kit and .opencode/skills/moq-kit in your project.

What does Moq Kit need to run?

Going by SKILL.md and its folder, Moq Kit needs the command-line tools its instructions call (mise).

Does Moq Kit access the network?

SKILL.md names 2 domains. In commands or code: github.com; the agent is likely to contact it when it follows the instructions. As links in the text: mise.jdx.dev. This is read from the text; nothing was executed.

Is Moq Kit safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Moq Kit use?

Moq Kit is published under the Apache-2.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Moq Kit use?

About 5k tokens (SKILL.md is roughly 20k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 7.9k tokens, read only when the agent opens those files.

What are the alternatives to Moq Kit?

Skills that share tags, products or a category with Moq Kit: Expo Brownfield Integration (mweinbach/agent-coworker, 156 stars), Simulator Audio E2E (hyochan/react-native-nitro-sound, 961 stars), Expo Brownfield (expo/skills, 2.7k stars) and Mobile Apps Create (forcedotcom/sf-skills, 1.1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Moq Kit?

software-mansion-labs (a GitHub organization) maintains it in software-mansion-labs/skills, which has 291 GitHub stars. The repository holds 20 skills in this directory. The repository was last updated on September 28, 2026.

Source: software-mansion-labs/skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.