| Platform | Architectures |
|---|---|
| macOS | arm64, x86_64 |
| Linux | x86_64, aarch64 (glibc) |
| Windows | x86_64 |
| Android | aarch64, armv7 (requires building from source) |
- API reference: Kotlin API docs
- Example app: hello-iroh-ffi, a Jetpack Compose demo that streams live positions between two devices
- All languages: platform support matrix
computer.iroh:iroh.
Prerequisites
- A JDK (21 or newer) and
javaon yourPATH - Gradle
Install
In yourbuild.gradle.kts:
The published artifact is single-platform. It does not yet ship a multiplatform build, so it won’t cover Android or arbitrary host triples out of the box. If you need a target the artifact doesn’t cover, build the bindings from source.
Hello, iroh
computer.iroh package. The API mirrors the Swift and Python bindings: same Endpoint.bind, same EndpointOptions, same presets.
Next steps
Connect two endpoints
Walkthrough of endpoints, tickets, and ALPNs. Code samples are Rust but APIs map 1:1 to Kotlin.
hello-iroh-ffi example app
A full working Jetpack Compose demo: two devices stream live positions to each other at 60 Hz and show whether the connection is direct or relayed.
Kotlin API reference
Generated Dokka reference for the
computer.iroh package.iroh-ffi on GitHub
Source, Kotlin tests, and issue tracker.
Foreground and backgrounding
On Android, the OS aggressively suspends background processes: sockets get torn down, threads stop scheduling, and an iroh endpoint that was happily accepting connections a moment ago goes silent. Treat each foreground/background transition as a lifecycle event for your endpoint:- Going to background: call
ep.shutdown()to close cleanly and release sockets. Persist the endpoint’s secret key (ep.secretKey().toBytes()) somewhere durable (e.g.EncryptedSharedPreferences) so the next bind keeps the same endpoint id. - Returning to foreground: re-bind with
EndpointOptions(secretKey = persistedBytes, preset = presetN0(), ...). Discovery republishes the new direct addresses automatically. - Staying live while backgrounded: run iroh inside an Android foreground service (with the appropriate
FOREGROUND_SERVICE_*permission for your use case). Without one, Android will eventually kill the network sockets regardless of how the coroutine scope is structured.
shutdown() on exit.
Building from source
For Android, an unsupported host, or to hack on the bindings themselves, clone iroh-ffi and generate the sources locally:kotlin/lib/src/main/kotlin/ and the native library is staged into kotlin/lib/src/main/resources/. Point your project at that lib module via settings.gradle.kts to consume it instead of the Maven artifact.
For Android, install the Android NDK via Android Studio and point Cargo at it via .cargo/config.toml. The relevant ABI targets are aarch64-linux-android, armv7-linux-androideabi, i686-linux-android, and x86_64-linux-android. The full NDK config template is in the iroh-ffi Kotlin README.