Core Libraries in the iroh Project: A Complete Guide to the n0-computer/iroh Rust Workspace
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 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, this crate exposes the high-level API that aggregates functionality from the other core libraries.
Key implementation details reside in 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, 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, 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) 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, with QUIC-specific optimizations in 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, 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 files:
tokio— Asynchronous runtime for networking, timers, and I/O across all cratesnoq/noq-proto/noq-udp— Low-level QUIC implementation powering the peer-to-peer transport layerserde/serde_json— Serialization of configuration, protocol messages, and persistent stateurl— Parsing and validation of relay URLs and PKARR recordsreqwest— HTTP client for DNS-over-HTTPS queries and relay API communicationiroh-metrics— Unified telemetry collection for both client and relay componentsrustls(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:
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:
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:
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— Core runtime that creates QUIC connections and exposes the public APIiroh-base/src/lib.rs— Definitions for keys, endpoint addresses, and common utilitiesiroh-dns/src/dns.rs— DNS resolver implementation with system fallback and DoH supportiroh-relay/src/server.rs— Main relay server implementation handling HTTP and QUICiroh-relay/src/quic.rs— QUIC-specific optimizations for the relay protocoliroh-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:
irohprovides the high-level client API for QUIC connections and hole-punchingiroh-basesupplies shared primitives and cryptographic types used across the workspaceiroh-dnsenables peer discovery via DNS-over-HTTPS and PKARR resolutioniroh-relayimplements fallback servers for NAT traversal when direct connections failiroh-dns-serveroffers 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →