# Core Libraries in the iroh Project: A Complete Guide to the n0-computer/iroh Rust Workspace

> Discover the core libraries in the iroh project: iroh, iroh-base, iroh-dns, iroh-relay, and iroh-dns-server. Learn about peer-to-peer QUIC, hole-punching, and DNS discovery.

- Repository: [number zero/iroh](https://github.com/n0-computer/iroh)
- Tags: deep-dive
- Published: 2026-07-12

---

**The iroh project consists of five tightly-coupled crates—`iroh`, `iroh-base`, `iroh-dns`, `iroh-relay`, and `iroh-dns-server`—that together provide peer-to-peer QUIC connections, hole-punching, and DNS-based peer discovery.**

The n0-computer/iroh repository is organized as a Rust workspace containing the core libraries that power its peer-to-peer networking stack. These crates form the public API responsible for establishing direct connections between peers, handling NAT traversal, and resolving addresses via DNS. Understanding the core libraries in the iroh project is essential for developers building distributed applications on this protocol.

## The Five Core Libraries in the iroh Project

The workspace architecture divides functionality into discrete crates that handle specific layers of the networking stack. Each crate maintains its own [`Cargo.toml`](https://github.com/n0-computer/iroh/blob/main/Cargo.toml) and source directory while depending on the shared primitives defined in `iroh-base`.

### iroh: The Primary Client Library

The **`iroh`** crate serves as the main entry point for application developers. It implements peer-to-peer QUIC connections, hole-punching via STUN, and multiplexed streams for bidirectional communication. According to the [`iroh/Cargo.toml`](https://github.com/n0-computer/iroh/blob/main/iroh/Cargo.toml), this crate exposes the high-level API that aggregates functionality from the other core libraries.

Key implementation details reside in [`iroh/src/runtime.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/runtime.rs), where the `Runtime` struct initializes the **noq** QUIC stack and manages connection state. This crate coordinates the network report system (`NetReport`) to assess NAT conditions before attempting direct connections.

### iroh-base: Shared Primitives and Utilities

The **`iroh-base`** crate defines the fundamental types used across the entire workspace. Located in [`iroh-base/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/lib.rs), this library handles key generation, endpoint addressing, and serialization primitives.

All other crates depend on `iroh-base` for consistent handling of peer identities and wire formats. This centralized approach ensures type safety when passing data between the DNS, relay, and transport layers.

### iroh-dns: DNS Resolution and PKARR Support

The **`iroh-dns`** crate provides DNS resolution capabilities including DNS-over-HTTPS (DoH) and PKARR (Public Key Addressable Resource Records) support. As implemented in [`iroh-dns/src/dns.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-dns/src/dns.rs), this library enables peers to discover each other via public DNS records rather than requiring static IP addresses.

The `DnsResolver` struct handles both system resolver fallback and encrypted DNS queries, while the `PkarrResolver` (defined in [`iroh-dns/src/pkarr.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-dns/src/pkarr.rs)) resolves human-readable names to public keys and relay addresses.

### iroh-relay: NAT Traversal and Relay Servers

When direct peer-to-peer connections are impossible due to aggressive NAT configurations, the **`iroh-relay`** crate provides fallback infrastructure. This crate implements both HTTP and QUIC relay servers that forward encrypted traffic between peers.

The main server logic resides in [`iroh-relay/src/server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server.rs), with QUIC-specific optimizations in [`iroh-relay/src/quic.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/quic.rs). The `RelayServer` struct binds to configured addresses and maintains secure tunnels for proxied connections.

### iroh-dns-server: Optional DNS-over-HTTPS Hosting

The **`iroh-dns-server`** crate provides a standalone binary for hosting DNS-over-HTTPS servers. While optional, this component allows operators to run their own PKARR record infrastructure rather than relying on public resolvers.

Implementation details are found in [`iroh-dns-server/src/server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-dns-server/src/server.rs), which handles HTTPS termination and record storage for the PKARR system used by `iroh-dns`.

## Key External Dependencies

While the core libraries in the iroh project provide the application logic, they rely on specific third-party crates declared across the workspace [`Cargo.toml`](https://github.com/n0-computer/iroh/blob/main/Cargo.toml) files:

- **`tokio`** — Asynchronous runtime for networking, timers, and I/O across all crates
- **`noq` / `noq-proto` / `noq-udp`** — Low-level QUIC implementation powering the peer-to-peer transport layer
- **`serde` / `serde_json`** — Serialization of configuration, protocol messages, and persistent state
- **`url`** — Parsing and validation of relay URLs and PKARR records
- **`reqwest`** — HTTP client for DNS-over-HTTPS queries and relay API communication
- **`iroh-metrics`** — Unified telemetry collection for both client and relay components
- **`rustls`** (optional) — TLS backend selectable via feature flags (`tls-ring`, `tls-aws-lc-rs`)
- **`portmapper`** (optional) — NAT port-mapping utilities for enhanced hole-punching on non-WASM platforms

## Working with the Core Libraries: Code Examples

The following snippets demonstrate practical usage of the core libraries in real-world scenarios.

### Establishing a QUIC Connection

To create a peer-to-peer connection using the `iroh` crate, initialize the `Runtime` and connect via public key:

```rust
use iroh::runtime::Runtime;
use iroh::net_report::NetReport;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Initialize the runtime (uses noq under the hood)
    let rt = Runtime::new().await?;

    // Request a network report to assess NAT traversal capabilities
    let _report = NetReport::fetch(&rt).await?;

    // Connect to a remote peer using its public key
    let peer_pubkey = "a1b2c3...".parse()?;
    let conn = rt.connect(peer_pubkey).await?;

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

    Ok(())
}

```

### Resolving PKARR Records

Use `iroh-dns` to resolve human-readable addresses to peer endpoints:

```rust
use iroh_dns::dns::DnsResolver;
use iroh_dns::pkarr::PkarrResolver;
use url::Url;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let resolver = DnsResolver::new().await?;
    let pkarr = PkarrResolver::new(resolver);
    let url: Url = pkarr.resolve("example.iroh").await?;
    println!("Resolved PKARR to: {}", url);
    Ok(())
}

```

### Running a Relay Server

Deploy a relay server to assist peers behind restrictive NATs:

```rust
use iroh_relay::server::RelayServer;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Start server with default settings; TLS is optional
    let server = RelayServer::bind("0.0.0.0:7777").await?;
    println!("Relay listening on {}", server.local_addr());
    server.run().await?;
    Ok(())
}

```

## Architecture Overview: Key Source Files

Understanding the relationship between these files clarifies how the core libraries interact:

- **[`iroh/src/runtime.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/runtime.rs)** — Core runtime that creates QUIC connections and exposes the public API
- **[`iroh-base/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/lib.rs)** — Definitions for keys, endpoint addresses, and common utilities
- **[`iroh-dns/src/dns.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-dns/src/dns.rs)** — DNS resolver implementation with system fallback and DoH support
- **[`iroh-relay/src/server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server.rs)** — Main relay server implementation handling HTTP and QUIC
- **[`iroh-relay/src/quic.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/quic.rs)** — QUIC-specific optimizations for the relay protocol
- **[`iroh-dns-server/src/server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-dns-server/src/server.rs)** — Stand-alone DNS-over-HTTPS server for PKARR hosting

## Summary

The core libraries in the iroh project provide a complete stack for peer-to-peer networking:

- **`iroh`** provides the high-level client API for QUIC connections and hole-punching
- **`iroh-base`** supplies shared primitives and cryptographic types used across the workspace
- **`iroh-dns`** enables peer discovery via DNS-over-HTTPS and PKARR resolution
- **`iroh-relay`** implements fallback servers for NAT traversal when direct connections fail
- **`iroh-dns-server`** offers optional infrastructure for self-hosted PKARR resolution

These crates work together with the **noq** QUIC implementation and **tokio** async runtime to deliver a production-ready framework for distributed applications.

## Frequently Asked Questions

### What is the difference between iroh and iroh-base?

The **`iroh`** crate provides the high-level networking API including connection management and hole-punching, while **`iroh-base`** contains only the primitive types and utilities shared across the workspace. Applications typically depend on `iroh`, which internally uses `iroh-base` for key handling and addressing.

### Do I need to run iroh-dns-server to use iroh?

No, **`iroh-dns-server`** is optional. The `iroh-dns` client library can resolve PKARR records using public DNS-over-HTTPS resolvers. You only need `iroh-dns-server` if you want to host your own PKARR record infrastructure or operate a private discovery network.

### Which crate handles the actual QUIC transport?

The **`iroh`** crate coordinates the QUIC transport, but the underlying implementation uses the **noq** family of crates (`noq`, `noq-proto`, `noq-udp`). These external dependencies handle the low-level QUIC protocol specifics, while `iroh` manages connection lifecycle, hole-punching logic, and stream multiplexing.