iroh: peer-to-peer networking with QUIC + NAT traversal
iroh is a Rust library for peer-to-peer networking that lets you dial another device by its public key instead of chasing IP addresses that change. It adds QUIC connections plus NAT traversal to your app: it tries to hole-punch a direct path between two endpoints, and falls back to public relay servers when a direct route isn't possible.
Reach for iroh if you're building a Rust app where two devices need to talk directly — file sync, realtime collaboration, a mesh — and you don't want to run your own signaling and TURN stack. Dialing by public key with automatic hole-punching and relay fallback is the whole pitch, and it's a real one. Skip it if you're not on Rust (the FFI bindings exist but live in a separate, less-polished repo), if your traffic is fine going through a central server anyway, or if you need a frozen, spec'd stack — the API is still evolving between releases.
The problem it solves
Peer-to-peer networking is hard because IP addresses aren't stable identities: they change with the network, and most devices sit behind NATs that block inbound connections. The common workaround is to route everything through a central server, which costs money and adds a bottleneck and a single point of failure. iroh's premise — captured in its tagline 'IP addresses break, dial keys instead' — is to give each endpoint a stable public-key identity and handle the messy part, finding a path through NATs, for you.
What is it?
iroh is an open-source Rust library for peer-to-peer networking that adds QUIC transport and NAT traversal to your app. You dial another endpoint by its public key (an EndpointId), and iroh finds and maintains the fastest route — a direct hole-punched connection when it can, or a public relay server when it can't. Per the repository it's dual-licensed under Apache-2.0 and MIT, and it ships as a Cargo crate you add with `cargo add iroh`.
Why it's getting attention
Peer-to-peer is having a moment again as people build local-first and realtime apps that don't want a cloud middleman for every byte. iroh has roughly 11.5k stars, is written in Rust, and comes from n0 (N0, INC.), who also run the public relay infrastructure and, per the README, continuously measure iroh's performance. The composable-protocol angle — iroh-blobs, iroh-gossip, and iroh-docs building on the same connection layer — gives it more reach than a bare transport library.
Key features
- ✓Dial by public key: connect to an EndpointId and iroh finds the current route, wherever the device has moved to
- ✓NAT hole-punching for direct connections, with fallback to an open ecosystem of public relay servers when a direct path fails
- ✓QUIC transport (via the noq stack) giving authenticated encryption, concurrent streams with priorities, a datagram transport, and no head-of-line blocking
- ✓Composable protocols already built on iroh: iroh-blobs (BLAKE3 content-addressed transfer), iroh-gossip (pub/sub overlay), iroh-docs (eventually-consistent key-value store)
- ✓Its own DNS/Pkarr address lookup via iroh-dns-server for resolving EndpointIds
- ✓Self-hostable relays — the iroh-relay crate is the same code n0 runs in production
Best use cases
- •Syncing files or blobs between two user devices without a central server, using iroh-blobs
- •Realtime collaboration or presence where peers need low-latency direct connections
- •Building a publish-subscribe overlay across many peers with iroh-gossip
- •Adding device-to-device connectivity to a Rust app that would otherwise need a relay/TURN server
How to install / try
iroh is a Rust crate. Add it with `cargo add iroh`. To use it from other languages, the README points to a separate repo, iroh-ffi, for FFI bindings. Beyond that, per-crate setup for the relay, DNS, and base crates isn't spelled out in the README — that's not clearly documented there, so check the docs site (docs.iroh.computer) and docs.rs/iroh.
How to use
You create an endpoint with `Endpoint::bind()`, connect to a peer's address over an ALPN, and open a bidirectional QUIC stream. The connecting side from the README's echo example: ```rs const ALPN: &[u8] = b"iroh-example/echo/0"; let endpoint = Endpoint::bind().await?; // Open a connection to the accepting endpoint let conn = endpoint.connect(addr, ALPN).await?; // Open a bidirectional QUIC stream let (mut send, mut recv) = conn.open_bi().await?; send.write_all(b"Hello, world!").await?; send.finish()?; ``` The accepting side registers a `ProtocolHandler` on a `Router`. Rather than writing your own protocol, you can pull in a ready-made one like iroh-blobs or iroh-gossip. The full echo example lives in the repo.
Strengths
- ✓Dialing by public key with automatic hole-punching and relay fallback removes the signaling and TURN plumbing you'd otherwise build yourself
- ✓Built on QUIC, so you get encryption, multiplexed streams, and datagrams instead of rolling your own transport
- ✓You can self-host relays with the same iroh-relay code n0 runs in production, so you're not tied to their infrastructure
- ✓The protocol ecosystem (blobs, gossip, docs) means common jobs are already solved on top of the connection layer
Limitations & risks
- △Rust-first: comfortable use is from Rust; other languages go through iroh-ffi, a separate repo with a smaller surface and less polish
- △Hole-punching isn't guaranteed — some NAT and firewall setups force a fallback to relays, which reintroduces a server hop and latency
- △The API is still evolving; types and examples (Endpoint, Router, EndpointId) have shifted across releases, so pin versions and expect churn
- △Running your own relay and DNS for production means operating extra services (iroh-relay, iroh-dns-server), not just importing a crate
- △The README is light on non-Rust setup and per-crate configuration, so you'll lean on the external docs site
Alternatives
Who should try it — and who should skip
Rust developers building apps where devices connect directly — file sync, local-first tools, realtime features, meshes — and who'd rather not stand up their own signaling and relay stack. If you're on Rust and value direct connections with a graceful relay fallback, iroh fits. If you're not on Rust, need browser support, or want a frozen stable API, look at WebRTC, libp2p, or wait for iroh's API to settle.
Frequently asked questions
iroh is an open-source Rust library for peer-to-peer networking. It adds QUIC connections and NAT traversal to your app, letting you dial another device by its public key and maintaining the fastest route — direct when possible, relayed when not.
It tries to hole-punch a direct connection between the two endpoints. If that fails, it falls back to an open ecosystem of public relay servers, which you can also self-host with the iroh-relay crate.
The core library is Rust and easiest to use there. For other languages, the README points to iroh-ffi, a separate repository that provides FFI bindings.
Yes. It's open source and, per the repository, dual-licensed under Apache-2.0 and MIT, so you can use it under either license.
The project ships composable protocols: iroh-blobs for BLAKE3 content-addressed blob transfer, iroh-gossip for publish-subscribe overlay networks, and iroh-docs for an eventually-consistent key-value store.