# What is the Architecture of the iroh Node? A Deep Dive into the n0-computer/iroh Stack

> Explore the iroh node architecture, a powerful Rust stack enabling P2P QUIC endpoints with NAT traversal, relay fallback, and DNS resolution. Understand the n0-computer/iroh components for seamless connectivity.

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

---

**The iroh node architecture comprises four specialized Rust crates—`iroh`, `iroh-relay`, `iroh-base`, and `iroh-dns-server`—that together provide a unified peer-to-peer QUIC endpoint with automatic NAT traversal, relay fallback, and DNS-based address resolution.**

The n0-computer/iroh repository implements a modern peer-to-peer networking stack written in Rust. Its architecture centers on the `Endpoint` abstraction, which combines QUIC transport, UDP hole-punching, and relay-based connectivity into a single cohesive node. Understanding this architecture reveals how iroh achieves seamless direct connections while gracefully handling complex network conditions like NATs and firewalls.

## Core Architectural Components

The iroh workspace is organized as a multi-crate Rust project where each crate handles a specific layer of the networking stack.

### iroh: The Core Endpoint Library

The `iroh` crate serves as the primary interface for applications. Located in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs), it implements the **`Endpoint`** type along with its **`Builder`** and **`Connection`** handles. This crate manages the full connection lifecycle, including hole-punching logic for NAT traversal, QUIC handshake coordination, and the high-level API that developers interact with. The `Endpoint` holds an `Arc<EndpointInner>` that owns the underlying QUIC implementation (via **noq**) and a `RelayMap` for relay configuration.

### iroh-relay: Relay Infrastructure

The `iroh-relay` crate provides both client and server implementations for scenarios where direct connectivity fails. The server component, found in [`iroh-relay/src/server/http_server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server/http_server.rs), runs the public relay infrastructure that forwards encrypted traffic between peers. Key types include **`RelayServer`**, **`RelayClient`**, and **`RelayMap`**. When embedded in an endpoint, the relay client opens QUIC-tunneled streams to remote relay servers, enabling communication even when both peers are behind restrictive NATs.

### iroh-base: Shared Primitives

The `iroh-base` crate contains the foundational types used across the entire workspace. Defined in [`iroh-base/src/endpoint_addr.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/endpoint_addr.rs), this crate provides **`EndpointId`** (public key-based identifiers), **`RelayUrl`** (relay server addresses), and **`EndpointAddr`** (composite addresses that may contain both direct socket addresses and relay URLs). These primitives ensure type safety and consistency between the core endpoint, relay client, and DNS components.

### iroh-dns-server: Address Resolution

The `iroh-dns-server` crate implements the DNS infrastructure that resolves **Pkarr** (public-key-address) records to endpoint IDs. Located in [`iroh-dns-server/src/server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-dns-server/src/server.rs), this server enables "`.dns.iroh.link`" lookups, allowing peers to discover each other's current network addresses without hardcoding IP addresses. The **`DnsServer`** and **`EndpointInfo`** types manage this resolution service.

## How the iroh Node Works: Connection Lifecycle

The architecture follows a six-phase lifecycle for establishing and maintaining peer-to-peer connections:

1. **Endpoint Creation** – Applications initialize an `Endpoint` via `Endpoint::builder()` or the convenience `Endpoint::bind()` method. The builder configures TLS certificates, QUIC parameters, address lookup services, and populates the initial `RelayMap` with default or custom relay URLs.

2. **Address Resolution** – When dialing a peer by its public key (`EndpointId`), the endpoint queries configured `AddressLookup` services. The DNS server resolves Pkarr records to `EndpointAddr` structures, which may contain direct socket addresses, relay URLs, or both.

3. **Connection Establishment** – The endpoint attempts connectivity in priority order:
   - **Direct Path**: If the `EndpointAddr` contains reachable socket addresses, the endpoint initiates a direct QUIC handshake using the underlying noq transport via `noq_endpoint().connect`.
   - **Relay Fallback**: If direct addresses are unavailable or unreachable, the endpoint selects a `RelayUrl` from its `RelayMap` and establishes a relayed connection through the `iroh-relay` infrastructure.

4. **Hole-Punching** – When both peers are behind NATs, the core `iroh` crate initiates a UDP hole-punching procedure before falling back to relays. This process leverages QUIC datagram transport to discover mutually routable paths, potentially upgrading a relayed connection to a direct one.

5. **Data Exchange** – Once established, the **`Connection`** type provides methods like `open_bi()` and `open_uni()` to create bidirectional or unidirectional streams. These streams inherit QUIC's features including congestion control, stream multiplexing, and ordered delivery.

6. **Metrics and Monitoring** – The `iroh` crate exposes `EndpointMetrics` for connection statistics, while the relay server provides HTTP-based metrics endpoints defined in [`iroh-relay/src/server/metrics.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server/metrics.rs).

## Key Source Files in the iroh Architecture

The implementation spans several critical files that define the system's behavior:

- **[`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs)** – Core `Endpoint` implementation, builder patterns, and connection management logic.
- **[`iroh-relay/src/server/http_server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server/http_server.rs)** – HTTP-based relay server that accepts QUIC streams from peers and forwards traffic.
- **[`iroh-base/src/endpoint_addr.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/endpoint_addr.rs)** – Shared address representations including `EndpointAddr` and `EndpointId`.
- **[`iroh-dns-server/src/server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-dns-server/src/server.rs)** – DNS server implementation for Pkarr record resolution.

## Building an iroh Node: Code Example

The following example demonstrates how the architectural components work together in practice:

```rust
use iroh::Endpoint;
use std::sync::Arc;

// 1. Build a default endpoint (binds to a random UDP port).
let endpoint = Endpoint::builder(Default::default())
    .bind()
    .await
    .expect("failed to bind");

// 2. Insert a public relay (optional – the default config already contains the public relays).
use iroh_base::RelayUrl;
use iroh::relay::RelayConfig;

let relay = RelayUrl::parse("https://relay.iroh.link")
    .expect("invalid relay URL");
endpoint.insert_relay(relay, Arc::new(RelayConfig::default()))
    .await;

// 3. Connect to a remote peer by its public key (represented as an EndpointId).
use iroh_base::EndpointId;

let remote_id = EndpointId::from_hex("deadbeef…").unwrap();
let alpn = b"my-protocol/1";
let conn = endpoint
    .connect(remote_id, alpn)
    .await
    .expect("connection failed");

// 4. Send and receive data over a bidirectional QUIC stream.
let (mut send, mut recv) = conn.open_bi().await?;
send.write_all(b"hello iroh!").await?;
send.finish()?;
let response = recv.read_to_end(1024).await?;
println!("peer replied: {}", String::from_utf8_lossy(&response));

```

## Summary

The iroh node architecture delivers a complete peer-to-peer networking solution through:

- **Four specialized crates** (`iroh`, `iroh-relay`, `iroh-base`, `iroh-dns-server`) that separate concerns between transport, relaying, primitives, and discovery.
- **Unified Endpoint abstraction** that handles direct QUIC connections, NAT hole-punching, and automatic relay fallback.
- **DNS-based address resolution** via Pkarr records, enabling persistent peer identifiers independent of network topology.
- **Built-in observability** through metrics exposed by both the endpoint and relay server components.

## Frequently Asked Questions

### How does the iroh node handle NAT traversal?

The iroh node implements UDP hole-punching in the core `iroh` crate, which attempts to discover directly routable paths between peers behind NATs before falling back to relay servers. This process uses QUIC datagram transport to coordinate NAT mapping discovery between endpoints.

### What is the relationship between the iroh endpoint and QUIC?

The `Endpoint` type in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) wraps a noq-based QUIC implementation, exposing high-level methods like `connect()` and `accept()` while managing the underlying TLS configuration, ALPN negotiation, and connection state. Applications interact with QUIC streams through the `Connection` type without managing low-level QUIC details.

### When does the iroh node use relay servers?

The node attempts direct connection establishment first using addresses from `EndpointAddr`. If the direct path fails or no direct addresses are available, the endpoint consults its `RelayMap` to select a `RelayUrl` and establishes a tunneled connection through the `iroh-relay` infrastructure, as implemented in [`iroh-relay/src/server/http_server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server/http_server.rs).

### How does address resolution work in the iroh architecture?

The `iroh-dns-server` resolves Pkarr (public-key-address) records to endpoint IDs, publishing these records at `dns.iroh.link`. When an application calls `Endpoint::connect()` with a remote peer's public key, the endpoint queries this DNS infrastructure to retrieve current `EndpointAddr` information containing both direct and relay addresses.