-
Notifications
You must be signed in to change notification settings - Fork 41
blog: iroh language support #468
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
9e42970
Add iroh language support blog post
okdistribute fd6cbf6
Use animated gif of accelerometer demo instead of static screenshot
okdistribute 5666556
blog: fix mDNS description in language-support post
okdistribute 0ea70e6
blog: add standard community footer to language-support post
okdistribute c639396
blog: fix Iroh Services link in language-support post
okdistribute 0dd8c3d
PR review
rklaehn 1179eb5
Update date
rklaehn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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) => <BlogPostLayout article={post} {...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. | ||
|
|
||
|  | ||
|
|
||
| ## 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. | ||
|
okdistribute marked this conversation as resolved.
|
||
|
|
||
| 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 | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.