btw: MoQ is under active development. The APIs and protocols are still evolving and will change. Most of this documentation is AI generated until things get more stable.

Skip to content

Kotlin Libraries

The Kotlin bindings expose Media over QUIC to Android apps and JVM-based services. Built on the same Rust core (moq-ffi) as the Python and Swift packages, wrapped with idiomatic Flow and coroutines.

Packages

dev.moq:moq

A single Kotlin Multiplatform module that publishes both JVM and Android variants under one coordinate. Consumers add dev.moq:moq:VERSION and Gradle metadata resolution picks the right artifact for their target.

Features:

  • Android (arm64-v8a, armeabi-v7a, x86_64) and desktop JVM (Linux, macOS, Windows)
  • Flow-based async sequences with structured cancellation
  • Native binaries bundled via JNI (Android) / JNA (desktop JVM)

Learn more

Installation

kotlin
// build.gradle.kts
dependencies {
    implementation("dev.moq:moq:0.2.0")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
}

Published to Maven Central via release-kt.yml. Native binaries for all supported targets are bundled in the artifact, so no extra setup is required on the consumer side.

Quickstart

kotlin
import dev.moq.*
import kotlinx.coroutines.flow.collect
import uniffi.moq.MoqClient
import uniffi.moq.MoqOriginProducer

// Wire an origin as both publish source and consume sink. Set just one
// side for a subscribe-only or publish-only client.
val origin = MoqOriginProducer()
val client = MoqClient()
client.setPublish(origin)
client.setConsume(origin)

val session = client.connect("https://relay.example.com")

origin.use {
    val consumer = origin.consume()
    val announced = consumer.announced("demos/")
    announced.announcements().collect { announcement ->
        println("got broadcast ${announcement.path()}")

        announcement.broadcast().subscribeCatalog().updates().collect { catalog ->
            println("catalog: $catalog")
        }
    }
}

session.shutdown()

Cancelling the surrounding coroutine scope propagates through to the native consumer's cancel() via the wrapper's onCompletion hook.

Source and issues

Licensed under MIT or Apache-2.0