IP addresses break, dial keys instead

Add peer-to-peer connectivity to your app, anywhere: servers, mobile apps, agents, desktops, and embedded systems.

spacedrive logo
nous logo
shaga logo
paycode logo
rave logo
delta_chat logo
holochain logo

Fast connections.
Anywhere.
Forever.

No VPNs, user accounts, or proprietary networks. The core peer-to-peer technology is open source and built on open standards, so you're never locked in: connect over our free community relays, self-host your own, or let us run them for you, and switch between them whenever you want.

“Doubling the network speed halves our compute budget.”

Ari Lotter
Principal Engineer at Nous
Read the Case Study
irohEmbeddedDevicePaymentTerminalMobilePhoneDesktopAppCloud

How are people using iroh?

Deploy, Monitor, Fix

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

iroh provides opt-in observability and network diagnostics. Track connection health and throughput across all your devices and services.

You'll see how much of your traffic goes direct versus through a relay: a fallback server iroh uses when two devices can't reach each other directly, always end-to-end encrypted. Compare plans.

Monitor your App
ConnectionsLatencyThroughputCustomΣAggregatorDashboardMobileServerIoT

Modular toolkit

Dozens of open-source, composable protocols built on top of iroh. Mix & match to get the feature set you need.

Start building.

Read the Docs

main.rs

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

#[tokio::main]
async fn main() -> Result<()> {
    // create the receive side
    let recv_ep = Endpoint::builder().bind().await?;
    let recv_router = Router::builder(recv_ep.clone())
        .accept(iroh_ping::ALPN, Ping::new())
        .spawn();
    recv_ep.online().await;
    let addr = recv_router.endpoint().addr();

    // create a send side & send a ping
    let send_ep = Endpoint::builder().bind().await?;
    let send_pinger = Ping::new();
    let rtt = send_pinger.ping(&send_ep, addr).await?;
    println!("ping took: {rtt:?} to complete");

    Ok(())
}

From the Blog