Deep dive into iroh: A replacement for WireGuard or a P2P layer for your application?

by Sylvain KerkourNarrated by speakeasy15:242,079 words
0:0015:24

Transcript

Deep dive into iroh: A replacement for WireGuard or a P2P layer for your application?

June 24, 2026

Just last week, the iroh project announced the release of its v1.0. What is iroh?

Well, I'm glad you're asking because it's a very interesting project that I'm following for some time for the technical wizardery they are doing with QUIC, BLAKE3 and a few other protocols, so I'm excited to share with you what I know about it and how it can be useful for you.

The TL;DR is that iroh is a library and an architectural pattern to establish peer-to-peer QUIC connections between machines, even if they are behind routers (NAT gateways). It's not a replacement for WireGuard, HTTPS or BitTorrent, instead, it's a building block that you can use to build applications on top of it, but you need to bring your own application protocol and business logic. It's just a very dumb, very reliable pipe between 2 machines anywhere in the world.

Image 1: iroh overview

What is iroh and how does it work

Interestingly, iroh is not a new protocol, it's a Rust library based on a specific architecture optimized for real-world peer-to-peer (P2P) communication and based on multiple existing standards.

P2P communication over IP requires UDP in order to punch through NATs. The problem is that UDP is not reliable so you generally have to build your own protocol on top of it.

Iroh's team noticed that a new protocol, QUIC (RFC 9000), provides reliable and secure communication over UDP, so they built a library and the infrastructure needed to establish QUIC connections directly between machines and punch through most NATs.

Unfortunately, punching through NATs (establishing P2P connections between machines behind routers) is not always guaranteed, so the added relays, which help endpoints to punch through NATs and, in the worst case, to relay traffic.

Image 2: iroh relays

Thanks to Rust, the team has been able to create bindings for many other languages such as JavaScript, Python, Kotlin and Swift.

Quickstart

There are great examples in the iroh repository, so here is the basic echo client / server example to give you an idea of how easy it is to get started.

// License MIT, N0, INC.
use iroh::{
 Endpoint, EndpointAddr,
 endpoint::{Connection, presets},
 protocol::{AcceptError, ProtocolHandler, Router},
};
use n0_error::{Result, StdResultExt};

/// Each protocol is identified by its ALPN string.
///
/// The ALPN, or application-layer protocol negotiation, is exchanged in the connection handshake,
/// and the connection is aborted unless both endpoints pass the same bytestring.
const ALPN: &[u8] = b"iroh-example/echo/0";

#[tokio::main]
async fn main() -> Result<()> {
 tracing_subscriber::fmt::init();
 let router = start_accept_side().await?;

 // wait for the endpoint to be online
 router.endpoint().online().await;

 connect_side(router.endpoint().addr()).await?;

 // This makes sure the endpoint in the router is closed properly and connections close gracefully
 router.shutdown().await.anyerr()?;

 Ok(())
}

async fn connect_side(addr: EndpointAddr) -> Result<()> {
 // address is automatically generated and the endpoint use N0's default relays and lookup service.
 let endpoint = Endpoint::bind(presets::N0).await?;
 let conn = endpoint.connect(addr, ALPN).await?;

 // Open a bidirectional QUIC stream
 let (mut send, mut recv) = conn.open_bi().await.anyerr()?;

 send.write_all(b"Hello, world!").await.anyerr()?;

 send.finish().anyerr()?;

 let response = recv.read_to_end(1000).await.anyerr()?;
 assert_eq!(&response, b"Hello, world!");

 conn.close(0u32.into(), b"bye!");

 endpoint.close().await;

 Ok(())
}

async fn start_accept_side() -> Result<Router> {
 // address is automatically generated and the endpoint use N0's default relays and lookup service.
 let endpoint = Endpoint::bind(presets::N0).await?;

 let router = Router::builder(endpoint).accept(ALPN, Echo).spawn();

 Ok(router)
}

#[derive(Debug, Clone)]
struct Echo;

impl ProtocolHandler for Echo {
 /// The `accept` method is called for each incoming connection for our ALPN.
 ///
 /// The returned future runs on a newly spawned tokio task, so it can run as long as
 /// the connection lasts.
 async fn accept(&self, connection: Connection) -> Result<(), AcceptError> {
 let endpoint_id = connection.remote_id();
 println!("accepted connection from {endpoint_id}");

 let (mut send, mut recv) = connection.accept_bi().await?;

 let bytes_sent = tokio::io::copy(&mut recv, &mut send).await?;
 println!("Copied over {bytes_sent} byte(s)");

 send.finish()?;

 connection.closed().await;

 Ok(())
 }
}

Concepts

Endpoint: Endpoints are iroh's "base unit". Connections are established between endpoints, so the first thing you need to do is to create an endpoint.

Address: With iroh, you don't connect directly to IP addresses. Instead, endpoints have addresses that are Ed25519 signing keys (what is an Ed25519 signing key? Read Signatures: The foundations of end-to-end encryption to learn more). That's the IP addresses break, dial keys instead line of the landing page.

Connection: An iroh connection is a QUIC connection between 2 endpoints. Connections basically have the same API as QUIC connections so you can create uni/bi-directional streams and send/receive datagrams.

One important thing to note is that an iroh / QUIC connection is certainly not what you are used to. Usually, you can expect a traditional TCP connection to be a single socket-to-socket stream, with a single physical path between your machine and the other.

Iroh leverages the QUIC multipath extension so that a single connection can actually flow through multiple physical paths (i.e. for 2 devices on the same local network one over an internet relay, the other through the local network) and all of that is abstracted for you. Thanks to QUIC, it can even migrate live connections between networks (e.g. WiFi then 4G) without interruptions.

Relays: Relays help endpoints punch holes through NATs and relay traffic when it's not possible. The generally need to be internet-reachable (e.g. servers in a datacenter). Relay can't decrypt the traffic between endpoints.

By default, iroh endpoints use "public" relays graciously provided by the N0 company (the organization behind iroh), but you can also host and use private relays.

Discovery / Lookup: You have the address (Ed25519 public key) of an endpoint, great! But how do you actually send packets to it? For that you need to look it up to translate the Ed25519 public key to an IP address or any other thing that you can contact over a transport.

By default iroh uses DNS and pkarr signed packets to map an Ed25519 key to IP addresses.

You can use custom Lookup mechanisms such as mDNS for local endpoints discovery.

Transport: As mentioned previously, iroh can establish connections over basically anything that can send and receive data packets. QUIC takes care of the reliability and encryption. Therefore, even if iroh's default transport is UDP, you can also build your own transport such as Bluetooth, Tor, radio or serial.

Protocol: Establishing connections is just the beginning, your application now has to talk to other endpoints to perform its duty. The application-level protocols are called "protocols" in iroh and are advertised in TLS' ALPN field (which QUIC uses under the hood). It's up to you to bring your own protocol(s) with a few provided by iroh's team such as Blobs and RPC, and a few others that are standardized, such as HTTP/3 (RFC 9114).

iroh vs ...

vs WireGuard / Tailscale

Tailscale is a company offering managed WireGuard tunnels between devices, whether it be your family's devices or a big organization's.

Tailscale (and more generally WireGuard) tunnels work at the device level. It tunnels the traffic for all the applications and Operating System services of your devices.

On the other hand, iroh works at the application level, it only tunnels traffic for a specific application.

That being said, you can ansolutely build an alternative to Tailscale that uses iroh under the hood and create a TUN interface on the machines. Actually, an iroh-based VPN would probably be better than Tailscale itself as WireGuard is easy to detect on the network and block while iroh uses standard QUIC packets.

vs QUIC

Iroh uses QUIC under the hood with multiple extensions such as QUIC Multipath to establish peer-to-peer tunnels.

Why the timing is (almost) perfect

While iroh is a long-time effort that has started many years ago, I believe that reaching 1.0 right now is an almost-perfect timing for 2 reasons.

First, because there is a growing sentiment against big tech companies that, after having achieved near-ubiquity and decimated almost all smaller players, are starting to "enshittify" the platforms (middlemen) they have built. At the same time happened the 2025 US election whose freshly elected administration made it clear to the world that the era of cooperation has come to an end, and that everything possible will be leveraged to gain short term power and dominance. Thus, the entire world is looking for alternatives to US Big Tech companies. Politicians looking for a quick win want to copy tech giants by filling the pockets of their friends with public money, but forward-looking people understand that nothing prevents History to repeat itself, and thus it's better to look how to build open and decentralized solutions. Iroh is a great fit here.

Around the same time, the invasion of Ukraine and industrial advances in China have revealed to the world the incredible leverage offered by cheap drones and robots. We are entering the era of (semi-)autonomous machines that need to communicate over heterogenous physical networks (radio, satellite, Wifi...) which is completely different that the traditional everything-over-internet (IP) model that we are used to.

As we are moving toward a world with more robots, more drone and more "intelligence" directly embedded into these machines, we need protocols to let them communicate directly with each other, in a peer-to-peer fashion. Eaxctly what iroh was designed for.

Roadmap

Unfortunately, the public roadmap stops at v1.0, so I'm not sure what are the next features coming soon, but here are my thoughts after playing a little bit with iroh.

I think that the 4 main topics that need improvement are:

  1. Change the landing page tagline to something like P2P made easy.
  2. Less "bloated" public API: I would prefer that more things are hidden and only have to care about a few high-level concepts.
  3. Easier integration with application-layer protocols: you are currently left on your own with a QUIC connection, but most developers would probably prefer something higher-level such as plug-and-play HTTP/3.
  4. Advanced routing and relay-to-relay communication: As seen before, iroh can work over different transports, so it would be great to be able to bridge these transports over multiple relays. Also, it could be great to have relays to be able to communicate directly, to get better performance as we can expect relay-to-relay internet routes to be better than machine-to-relay in a faraway country, which would improve the quality of, for example, video calls a lot, but also to provide more censorship resistance, think of an authoritarian country blocking outbound connections which could be circumvented with a network of relays in data centers.

Image 3: relay-to-relay communication

Closing Thoughts

QUIC is one of the greatest open standard of the decade and is far more than a simple TCP + TLS replacement (you can read more here about why I'm excited about QUIC), and iroh has found the perfect niche for it. Iroh is, in my opinion, one of the most promising projects of the decentralized world, I wish them well!

To learn more about iroh's internals, the best places to start are the blog and the documentation.

If you like cool decentralized technology, take a look at Reticulum, another protocol to send data packets over multiple physical layers such as LoRa, IP, Bluetooth or Serial.

Now, if you want to get your hands dirty and vibecode hack some of the crazy ideas you've been keeping in a corner of your mind, you need to know Rust.

In my book Black hat Rust you will not only learn what is Rust (what are generics, traits, iterators...), but also how to Rust: how to architect your Rust projects, which patterns should you use in Rust and which one you should avoid. In Black hat Rust we go from theory to practice and learn by doing many applied projects such as building a web server, and end-to-end encrypted Remote Access Tool (RAT), build shellcodes in Rust with #![no_std] instead of assembly and many other projects to get your hands dirty.

Tags:p2pperformanceprogrammingquicrustsecurity


Join the newsletter to get the latest updates

No spam ever, unsubscribe anytime and we will never share your email. You can also grab the RSS feed

Image 4: Black Hat Rust cover Want to learn Rust, offensive security and applied cryptography? Take a look at my book Black Hat Rust where, from theory to practice, you will build an end-to-end encryption protocol, exploits, a Remote Access Tool, craft shellcodes and many other things to get your hands dirty. Special Promotion: 50 € 25 €Special Promotion: $50 $25

speakeasy app icon

speakeasy

Turn reading into listening

Get
AGES
4+
Years
CATEGORY
Education
DEVELOPER
STUDIO.GOLD
LANGUAGE
EN
English
SIZE
28
MB
speakeasy home screen
Paste an article
Audio player
Supported sources
Playback speed
Local library
iPhone

Turn any article into natural-sounding audio. Paste a link, press play, and stay informed while you move.

Coming soon on Android

Turn any article into audio

speakeasy converts URLs from Twitter, Medium, Substack, and any blog into natural-sounding audio. Listen on your commute, at the gym, or wherever you go.

Get speakeasy Free

Think this audio shouldn't be here? Request a takedown.