p2p that just works

Iroh is a library for building on direct connections between devices, putting more control in the hands of your users.

Trusted at scale by the world's most innovative teams

spacedrive logo
nous logo
shaga logo
rave logo
delta_chat logo
recall logo

Delta Chat uses iroh to power in-chat apps for hundreds of thousands of devices around the world, even when internet access is precarious.

DIRECTDIRECTRELAYDIRECT

Connect any two devices on the planet

Iroh gives you an API for dialing by public key. You say “connect to that phone”, iroh will find & maintain the fastest connection for you, regardless of where it is.

“In stark contrast to other p2p & dweb technologies we've played with - which are exciting due to their implications for the future - Iroh brought instant gains in our present."

- weird.one

Compose your own tailor-made protocol stack

An ecosystem of ready-made, composable protocols are built on top of iroh.
Mix & match to get the feature set you need.

Build your own protocol

Don't see a protocol you need? Build your own! Iroh gives you a reliable foundation for building distributed systems that reach the edge. The rest is up to you.

Protocol Docs

Continuously Measured

All commits to iroh's main branch run through a growing set of simulations & tests

Iroh Perf Site

Real World Use

Iroh is running in production on millions of devices, on all major platforms.

Delta Chat

Delta Chat

Iroh powers multi-device backup & live connections for in-chat WebXDC apps

Build something amazing, today.

Start Building

main.rs

// a program that creates two endpoints & sends a ping between them
use anyhow::Result;
use iroh::{Endpoint, protocol::Router};
use iroh_ping::{ALPN as PingALPN, Ping};

#[tokio::main]
async fn main() -> Result<()> {
    // create the receive side
    let recv_endpoint = Endpoint::builder().discovery_n0().bind().await?;
    let recv_router = Router::builder(recv_endpoint)
      .accept(PingALPN, Ping::new())
      .spawn();

    // get the receive side's address:
    let addr = recv_router.endpoint().node_addr().await?;

    // create the send side & send a ping!
    let send_ep = Endpoint::builder().discovery_n0().bind().await?;
    let send_pinger = Ping::new();
    send_pinger.ping(&send_ep, addr).await?;

    // ok!
    Ok(())
}

From the Blog

IRPC

A lightweight rpc crate for iroh protocols