diff --git a/public/blog/iroh-language-support/accelerometer-demo.gif b/public/blog/iroh-language-support/accelerometer-demo.gif new file mode 100644 index 00000000..4cc25013 Binary files /dev/null and b/public/blog/iroh-language-support/accelerometer-demo.gif differ diff --git a/src/app/blog/iroh-language-support/page.mdx b/src/app/blog/iroh-language-support/page.mdx new file mode 100644 index 00000000..98dcd589 --- /dev/null +++ b/src/app/blog/iroh-language-support/page.mdx @@ -0,0 +1,154 @@ +import { BlogPostLayout } from '@/components/BlogPostLayout' + +export const post = { + draft: false, + author: 'okdistribute', + date: '2026-06-18', + title: 'iroh language support', + description: + 'Announcing Swift, Kotlin, Python, and JavaScript bindings with first-party support for iroh.', +} + +export const metadata = { + title: post.title, + description: post.description, +} + +export default (props) => + +We’re excited to announce [Swift], [Kotlin], [Python], and [JavaScript] bindings with first-party support for iroh! + +To get started with the bindings, follow the [getting-started guide for your language of choice]. + +The bindings expose **QUIC data streams**. From any device, you can quickly open a direct connection to any other device, either across the room or across the world, as long as you know its [**EndpointId**][EndpointId]. + +As endpoints connect, you can monitor their direct data rate: the percentage of traffic sent directly between devices instead of over [relays]. Expect a 95–99% direct connection rate, depending on your use case and where in the world you deploy. Connections are always end to end encrypted using TLS. + +## Platforms supported + +Iroh supports all major platforms: + +- iOS +- macOS (arm64, no Intel build) +- Android +- Linux +- Windows +- FreeRTOS + +For per-language details, see the [platform support matrix]. + +## Quick accelerometer demo + +For an out-of-the-box demo, check out our [accelerometer demo]. + +Each peer controls one dot in a shared coordinate space. You move your dot by tilting the phone or dragging on the desktop, and you stream its position to the other peer at ~60 Hz over an iroh bi-directional stream. The peer renders your dot at the same coordinates next to its own, so both screens show the two dots tracking each other in real time. + +The two peers are fully symmetric. While connected, a line under the status shows the connection's [live network paths] — direct vs. relay, remote address, and RTT — so you can watch iroh [hole-punch] its way from a relayed connection to a direct one. + +![The accelerometer demo connected to a peer, showing both dots and the connection's live network paths](/blog/iroh-language-support/accelerometer-demo.gif) + +## Sending streaming data + +Once [two endpoints are connected], you talk over plain QUIC streams. Open a bi-directional stream with `openBi()` on the dialing side and accept it with `acceptBi()` on the other, then write bytes into one end and read them out the other. Streams are ordered, backpressured, and end-to-end encrypted, and a single connection can carry as many of them as you need. There's no broker or polling loop in the middle. + +Most apps will have a similar shape in every language: + +- a **send loop** +- a **receive loop** + +Here's what that looks like in Swift for the accelerometer demo: + +```swift +// Dial a peer anywhere in the world by its EndpointId +let addr = EndpointAddr(id: peerId, relayUrl: nil, addresses: []) +let conn = try await endpoint.connect(addr: addr, alpn: WireFormat.alpn) +let bi = try await conn.openBi() // the other side calls conn.acceptBi() + +// Send loop: stream your dot's position at ~60 Hz +Task { + let send = bi.send() + while !Task.isCancelled { + let frame = WireFormat.encodePosition(x: game.myPos.x, y: game.myPos.y) + try await send.writeAll(buf: frame) + try await Task.sleep(nanoseconds: 16_666_000) + } +} + +// Receive loop: read the peer's frames as they arrive +Task { + let recv = bi.recv() + while !Task.isCancelled { + let body = try await recv.readExact(size: WireFormat.positionFrameSize) + if let pos = WireFormat.decodePosition(body) { + game.receivedTheirPos(x: pos.x, y: pos.y) + } + } +} +``` + +## Monitor your application performance + +In any of the languages, you can also diagnose application performance and see direct data rate per endpoint by connecting an [Iroh Services] [API key]. + +In Swift, for example, it’s one call to enable services monitoring: + +```swift +let client = try await ServicesClient.create( + endpoint: endpoint, + options: ServicesOptions(apiSecret: "YOUR_API_KEY", name: "my-endpoint") +) +``` + +The [metrics dashboard] helps you answer questions like: + +- How many endpoints are online right now? +- How much of my traffic is direct vs. relayed? High relay usage can signal application code or deployment issues. +- What is my throughput over time: data sent and received, broken down by connection type (direct IPv4, direct IPv6, or relayed)? +- What version of iroh are my endpoints running? + +### Diagnosing a connectivity issue + +From any of the bindings, you can manually submit a network diagnostics report to iroh services: + +```swift +try await client.submitNetworkDiagnostics(send: true) +``` + +This sends a [network diagnostics report], covering NAT type, UDP connectivity, relay latency, port mapping protocol availability, and direct addresses. Everything you need to debug connection issues. + +## Future work + +Right now, the bindings support creating real-time data streams between two or more devices. In the future, we’d like to also add support for popular use cases, such as [RPC], [gossip], [blobs] and [documents]. + +Soon we will also introduce out of the box [mDNS] and [Bluetooth] support in the FFI; right now, these are Rust-only features because the custom address-lookup and transport APIs they build on aren't 100% stable yet. Stay tuned. + +You don’t have to wait, though: the stream API is already everything you need to build production-grade powerful, low-latency apps today. + +If you need help getting started or just want to chat, please join us on [Discord]! And to keep up with all things iroh, check out our [Twitter], [Mastodon], and [Bluesky]. + +[Swift]: https://docs.iroh.computer/languages/swift +[Kotlin]: https://docs.iroh.computer/languages/kotlin +[Python]: https://docs.iroh.computer/languages/python +[JavaScript]: https://docs.iroh.computer/languages/javascript +[getting-started guide for your language of choice]: https://docs.iroh.computer/languages/ +[EndpointId]: https://docs.iroh.computer/concepts/endpoints +[relays]: https://docs.iroh.computer/concepts/relays +[platform support matrix]: https://docs.iroh.computer/languages#platform-support +[accelerometer demo]: https://github.com/n0-computer/hello-iroh-ffi +[live network paths]: /blog/iroh-on-QUIC-multipath +[hole-punch]: https://docs.iroh.computer/concepts/nat-traversal +[two endpoints are connected]: https://docs.iroh.computer/connect-two-endpoints +[Iroh Services]: https://services.iroh.computer +[API key]: https://docs.iroh.computer/iroh-services/quickstart +[metrics dashboard]: https://docs.iroh.computer/iroh-services/metrics +[network diagnostics report]: https://docs.iroh.computer/iroh-services/net-diagnostics/quickstart +[RPC]: https://docs.rs/irpc +[gossip]: https://docs.rs/iroh-gossip +[blobs]: https://docs.rs/iroh-blobs +[documents]: https://docs.rs/iroh-docs +[mDNS]: https://docs.rs/iroh-mdns-address-lookup +[Bluetooth]: https://github.com/mcginty/iroh-ble-transport +[Discord]: https://discord.com/invite/DpmJgtU7cW +[Twitter]: https://x.com/iroh_n0 +[Mastodon]: https://mastodon.social/@n0iroh +[Bluesky]: https://bsky.app/profile/iroh.computer