# What is n0-computer/iroh? A Peer-to-Peer QUIC Networking Library in Rust

> Discover n0-computer/iroh a Rust library for secure peer-to-peer QUIC networking. Explore its NAT traversal relay fallback and DNS discovery features for robust connections.

- Repository: [number zero/iroh](https://github.com/n0-computer/iroh)
- Tags: getting-started
- Published: 2026-06-21

---

**n0-computer/iroh is a Rust workspace providing a high-level API for establishing direct, encrypted peer-to-peer connections over QUIC, with built-in NAT traversal, relay fallback, and DNS-based endpoint discovery.**

n0-computer/iroh is an open-source Rust library maintained by n0 computer that abstracts the complexity of peer-to-peer networking. Built atop the QUIC transport protocol, it enables developers to create direct connections between endpoints using cryptographic keys as identifiers, eliminating the need for manual NAT traversal or custom certificate management.

## Core Architecture of n0-computer/iroh

### Endpoint-Centric Design with Cryptographic Identity

At the heart of n0-computer/iroh lies the **`Endpoint`**, defined in [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs) and implemented in [`iroh/src/endpoint/mod.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/mod.rs). Each peer instantiates an `Endpoint` that owns a long-term key pair consisting of a **`SecretKey`** and **`PublicKey`**. The public key serves dual purposes: it acts as the cryptographic identity and as the **`EndpointId`**, eliminating the need for separate certificate authorities or DNS names.

Endpoints bind to UDP sockets and manage the entire connection lifecycle, from initial handshake to stream multiplexing. The builder pattern, accessible via `Endpoint::builder()`, allows configuration of ALPN protocols, relay settings, and address lookup mechanisms before calling `bind()` to activate the endpoint.

### Relay Infrastructure and NAT Traversal

By default, every endpoint connects to a **home relay** identified by a **`RelayUrl`**. The `iroh-relay` crate provides both client and server implementations, with the server logic residing in [`iroh-relay/src/server/http_server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server/http_server.rs). These relays forward encrypted traffic when direct connectivity is impossible.

When NAT traversal is required, iroh attempts **hole-punching** to establish a direct UDP path between peers. Once a direct route is discovered, traffic automatically migrates off the relay, optimizing for latency and throughput. This process is transparent to the application layer, requiring no manual intervention.

### Address Discovery via DNS

To connect peers without pre-sharing IP addresses, n0-computer/iroh implements **`DnsAddressLookup`** in [`iroh/src/address_lookup/dns.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/address_lookup/dns.rs). This module resolves an `EndpointId` to its current relay URL and direct addresses using DNS-based `pkarr` records. The `iroh-dns` crate provides the underlying resolver, while `iroh-dns-server` offers a standalone server implementation for hosting these records.

## Workspace Structure and Source Files

The n0-computer/iroh repository is organized as a Cargo workspace with clear separation of concerns:

- **[`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs)** – Public API façade, re-exporting `Endpoint`, `RelayUrl`, and connection types
- **[`iroh/src/endpoint/mod.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/mod.rs)** – Endpoint builder, connection management, and stream handling
- **[`iroh/src/address_lookup/dns.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/address_lookup/dns.rs)** – DNS-based discovery implementation
- **[`iroh-base/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/lib.rs)** – Shared primitives including `EndpointId`, `RelayUrl`, and cryptographic types
- **[`iroh-relay/src/server/http_server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server/http_server.rs)** – HTTP and QUIC server handling relay traffic forwarding
- **[`iroh-dns/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-dns/src/lib.rs)** – Core DNS resolver for `pkarr` record resolution
- **[`iroh-dns-server/src/main.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-dns-server/src/main.rs)** – Standalone DNS server for endpoint record publication

## Practical Usage: Establishing Connections

The following examples demonstrate the complete lifecycle of a peer-to-peer connection using n0-computer/iroh.

### Basic Echo Server and Client

This example shows a server accepting connections and echoing data back, while a client connects and exchanges messages:

```rust
use iroh::{Endpoint, EndpointAddr, endpoint::presets};
use n0_error::{Result, StdResultExt};

#[tokio::main]
async fn main() -> Result<()> {
    // Server setup
    let server_ep = Endpoint::builder(presets::N0)
        .alpns(vec![b"my-echo".to_vec()])
        .bind()
        .await?;

    // Spawn server task
    tokio::spawn(async move {
        let conn = server_ep.accept().await?.await?;
        let (mut send, mut recv) = conn.accept_bi().await?;
        tokio::io::copy(&mut recv, &mut send).await?;
        send.finish()?;
        conn.closed().await;
        Ok::<_, n0_error::Error>(())
    });

    // Client setup
    let peer_addr: EndpointAddr = /* obtain from DNS or configuration */ todo!();
    
    let client_ep = Endpoint::bind(presets::N0).await?;
    let conn = client_ep.connect(peer_addr, b"my-echo").await?;

    // Open bidirectional stream
    let (mut send, mut recv) = conn.open_bi().await?;
    send.write_all(b"Hello, iroh!").await?;
    send.finish()?;
    
    let mut buf = Vec::new();
    recv.read_to_end(&mut buf).await?;
    println!("Echo: {}", String::from_utf8_lossy(&buf));

    // Cleanup
    conn.close(0u32.into(), b"bye");
    client_ep.close().await;
    Ok(())
}

```

The implementation leverages **`open_bi()`** and **`accept_bi()`** for bidirectional streams, while **`accept()`** handles incoming connections. Note that streams are lightweight and can be created on-demand, though the sender must transmit data before the receiver's `accept_*` call returns.

### DNS-Based Address Lookup

For scenarios where direct IP addresses are unknown, configure the endpoint with `DnsAddressLookup`:

```rust
use iroh::{Endpoint, endpoint::presets};
use iroh::address_lookup::DnsAddressLookup;

#[tokio::main]
async fn main() -> Result<()> {
    let lookup = DnsAddressLookup::default();
    let ep = Endpoint::builder(presets::N0)
        .address_lookup(lookup)
        .alpns(vec![b"my-protocol".to_vec()])
        .bind()
        .await?;

    // Connect using only the EndpointId (public key)
    // ep.connect(endpoint_id, ...).await?;
    Ok(())
}

```

This configuration enables resolution of remote endpoints through the DNS infrastructure defined in [`iroh-dns/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-dns/src/lib.rs).

## Security and Encryption Model

n0-computer/iroh utilizes **TLS over QUIC** for all connections, but with a simplified trust model. Rather than traditional certificate chains, authentication relies on the **EndpointId** (the peer's `PublicKey`). When a connection is established, the endpoint automatically validates that the remote party possesses the private key corresponding to the claimed `EndpointId`, providing mutual authentication without certificate management overhead.

All traffic is encrypted end-to-end, including when traversing relay servers. The relay infrastructure in `iroh-relay` only forwards opaque encrypted packets and cannot inspect payload contents.

## Summary

- **n0-computer/iroh** is a Rust workspace providing high-level peer-to-peer networking over QUIC
- **Endpoints** use cryptographic key pairs (`SecretKey`/`PublicKey`) as identifiers, with the public key serving as the `EndpointId`
- **Relay support** enables connectivity behind NATs, with automatic migration to direct paths when hole-punching succeeds
- **DNS address lookup** allows discovery of peers using only their `EndpointId` via `DnsAddressLookup` in [`iroh/src/address_lookup/dns.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/address_lookup/dns.rs)
- **Stream multiplexing** supports both unidirectional and bidirectional QUIC streams created on-demand

## Frequently Asked Questions

### What transport protocol does n0-computer/iroh use?

n0-computer/iroh is built on top of **QUIC**, a modern transport protocol operating over UDP that provides built-in encryption, multiplexed streams, and connection migration. The library leverages QUIC's capabilities to handle multiple simultaneous streams over a single connection while maintaining low latency.

### How does n0-computer/iroh handle NAT traversal?

When direct connectivity is blocked by NAT, endpoints utilize a **home relay** (`RelayUrl`) to forward encrypted traffic. Simultaneously, the library attempts **hole-punching** to establish a direct UDP path. Once successful, traffic transparently migrates from the relay to the direct connection without dropping the connection or requiring application changes.

### What is the relationship between EndpointId and PublicKey?

In [`iroh-base/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/lib.rs), the `EndpointId` is defined as the **`PublicKey`** of the endpoint's key pair. This design choice eliminates the need for separate identifiers or certificate management, as the public key cryptographically identifies the peer and enables authentication during the QUIC handshake.

### Do I need to run my own relay server to use n0-computer/iroh?

No. The library defaults to using public relays operated by n0 computer (accessible via `presets::N0`). However, you can configure custom relays by specifying alternative `RelayUrl` values in the `Endpoint` builder, or run your own infrastructure using the `iroh-relay` crate and [`iroh-relay/src/server/http_server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server/http_server.rs) implementation.