What Are the Dependencies of the Iroh Project? A Complete Technical Breakdown

The iroh crate depends on 30+ direct dependencies including tokio for async runtime, blake3 for cryptographic hashing, ed25519-dalek for digital signatures, and internal workspace crates like iroh-base and iroh-relay, all declared in iroh/Cargo.toml at lines 24-64.

The iroh project, developed by n0-computer, is a Rust-based distributed systems toolkit for building peer-to-peer applications. Understanding the dependencies of the iroh project is essential for developers integrating its networking stack, as the crate orchestrates async I/O, cryptographic identity, and NAT traversal through a carefully curated set of external and internal libraries.

Core Runtime Dependencies

The foundation of iroh relies on mature crates from the Rust ecosystem, specified in the [dependencies] section of iroh/Cargo.toml.

Async Runtime and I/O

Tokio powers the entire asynchronous runtime. The manifest pins tokio to version 1.44.1 with features io-util, macros, sync, and rt defined across lines 54-59. Complementary utilities include:

  • tokio-stream (0.1.15, line 60) with the sync feature for stream combinators
  • tokio-util (0.7, line 61) providing codec and other I/O extensions
  • bytes (1.11, line 26) for zero-copy buffer management in network streams
  • pin-project (1, line 42) for ergonomic pinning of futures

Cryptographic Primitives

Security-critical operations depend on specialized hashing and signing libraries:

  • blake3 (1.8.3, line 25) provides fast cryptographic hashing for content-addressed identifiers, configured with no default features to minimize binary size
  • ed25519-dalek (=3.0.0-rc.0, line 31) handles public-key cryptography with features for serde, rand_core, zeroize, pkcs8, and pem support
  • rand (0.10, line 47) supplies cryptographically secure random number generation for keys and nonces
  • ctutils (0.4.0, line 27) offers constant-time utility functions to prevent timing attacks

Networking and Transport

The QUIC-based transport layer relies on the noq family of crates and TLS infrastructure:

  • noq (1.0.0, line 44) implements the QUIC protocol with rustls features
  • noq-proto (1.0.0, line 45) defines wire protocol structures
  • noq-udp (1.0.0, line 46) provides the UDP socket abstraction
  • rustls (0.23.33, line 50) serves as the TLS stack for secure connections
  • webpki-types (1.12, line 64) supplies X.509 certificate types via the rustls-pki-types alias
  • netwatch (0.19, line 40) monitors network interface changes (link up/down events)

Data Encoding and Serialization

Configuration and protocol messages use standard serialization formats:

  • serde (1.0.219, line 51) with derive and rc features for struct serialization
  • data-encoding (2.2, line 28) for Base-64 and Base-32 encoding of keys
  • url (2.5, line 63) with serde support for parsing relay and endpoint addresses
  • strum (0.28, line 53) with the derive feature for enum string conversions
  • derive_more (2.0.1, line 30) reduces boilerplate for standard trait implementations

Internal Workspace Dependencies

Iroh organizes its architecture into several interdependent crates within the same repository, referenced via path dependencies.

Core Iroh Crates

These workspace members define the public API and protocol logic:

  • iroh-base (1.0.0, line 34) located at ../iroh-base with features key and relay, providing core data structures like PublicKey and relay URLs
  • iroh-dns (1.0.0, line 35) at ../iroh-dns handles DNS-based peer discovery
  • iroh-relay (1.0.0, line 36) at ../iroh-relay (no default features) implements the relay server and client for NAT traversal

Utility Libraries

The n0-* ecosystem provides async helpers and system integration:

  • n0-future (0.3, line 37) supplies helper traits for async programming
  • n0-error (1.0.0, line 38) provides error handling wrappers compatible with anyhow
  • n0-watcher (1.0.0, line 39) implements filesystem watching for hot-reloading configuration
  • backon (1.4, line 24) offers retry utilities for unreliable network operations
  • papaya (0.2.3, line 41) provides fast, deterministic hashing utilities
  • rustc-hash (2, line 49) implements fast hash maps for internal caches
  • smallvec (1.11.1, line 52) optimizes collections with few elements
  • portable-atomic (1, line 43) ensures atomic operations work on all targets including WebAssembly

Platform-Specific and Optional Dependencies

Certain features are gated behind conditional compilation for specific targets.

Native Platform Features

On non-WebAssembly targets, iroh enables additional networking capabilities:

  • hickory-resolver (0.26.0, line 77) provides DNS resolution (no default features)
  • portmapper (0.19, line 78) optionally enables UPnP and NAT-PMP for automatic port mapping
  • noq lines 79-80 enable runtime-tokio and rustls features specifically for native platforms

WebAssembly Support

For wasm32 targets, iroh substitutes system dependencies with browser-compatible alternatives:

  • wasm-bindgen-futures (0.4, line 92) bridges Rust futures to JavaScript promises
  • time (0.3, lines 94-95) with wasm-bindgen feature for time handling in browsers
  • getrandom (0.4, lines 95-96) with wasm_js feature for secure random number generation in WebAssembly

How to Use Iroh in Your Project

To integrate these dependencies into your own application, add iroh to your Cargo.toml:

[dependencies]
iroh = { git = "https://github.com/n0-computer/iroh", rev = "main" }

The following examples demonstrate key functionality using the dependency graph described above.

Creating Peer Endpoints and Connections

This example uses tokio, iroh-base, and the noq transport stack to establish a connection:

use iroh::endpoint::Endpoint;
use iroh::iroh_base::key::PublicKey;
use std::net::SocketAddr;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Load the default endpoint (creates a keypair if none exists)
    let ep = Endpoint::default().await?;

    // Example: connect to a remote peer given its public key and socket
    let remote_key = PublicKey::from_hex("ab...")?;
    let remote_addr: SocketAddr = "127.0.0.1:4000".parse()?;
    let conn = ep.connect(remote_key, remote_addr).await?;

    println!("connected to {}!", conn.remote_id());
    Ok(())
}

The Endpoint struct is implemented in iroh/src/endpoint.rs, while PublicKey derives from the iroh-base crate declared at line 34 of the manifest.

Using the Relay Client for NAT Traversal

Leverage the iroh-relay dependency to connect through relays when direct connections fail:

use iroh::relay::RelayClient;
use iroh::iroh_base::relay_url::RelayUrl;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Connect to a public relay
    let relay_url = RelayUrl::parse("https://relay.iroh.example")?;
    let client = RelayClient::new(relay_url).await?;

    // Obtain a mapped address that can be shared with peers
    let mapped = client.register().await?;
    println!("relay address: {}", mapped);
    Ok(())
}

This functionality relies on the iroh-relay crate (line 36) and the HTTP types provided by the http crate (line 32).

File Transfer Example

The repository includes a complete file transfer example demonstrating the full stack:

use iroh::examples::transfer;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    transfer::run().await
}

The source for this demo resides at iroh/examples/transfer.rs, showcasing how the blake3 hashing (line 25) and serde serialization (line 51) work together to exchange content-addressed data over QUIC connections.

Summary

  • The iroh crate declares 30+ direct dependencies in iroh/Cargo.toml, ranging from the tokio async runtime to specialized crates like blake3 and ed25519-dalek.
  • Internal workspace crates (iroh-base, iroh-dns, iroh-relay) provide the core abstractions for identity, discovery, and NAT traversal.
  • Platform-specific dependencies enable WebAssembly support via wasm-bindgen-futures and native DNS resolution via hickory-resolver.
  • Key files include iroh/src/endpoint.rs for connection management and iroh-relay/src/client.rs for relay functionality, both consuming the dependency tree defined in the manifest.

Frequently Asked Questions

What async runtime does iroh use?

Iroh uses Tokio version 1.44.1 as its async runtime, declared at lines 54-59 of iroh/Cargo.toml with features for I/O utilities, macros, synchronization primitives, and the multi-threaded scheduler. The codebase also utilizes tokio-stream and tokio-util for extended async capabilities.

Does iroh support WebAssembly compilation?

Yes, iroh supports WebAssembly targets through conditional dependencies. When targeting wasm32, the crate uses wasm-bindgen-futures (line 92) to bridge Rust futures to JavaScript promises, getrandom with the wasm_js feature (lines 95-96) for entropy, and time with wasm-bindgen (lines 94-95) for clock functionality.

Which crate provides cryptographic hashing for content addressing?

Blake3 version 1.8.3 (line 25) provides the cryptographic hashing used for content-addressed identifiers in iroh. It is configured with no default features to keep the binary size minimal while providing fast, parallel hashing suitable for large file verification.

How does iroh handle NAT traversal?

Iroh implements NAT traversal through the iroh-relay workspace crate (line 36) combined with the optional portmapper dependency (line 78). The relay client (iroh-relay/src/client.rs) connects to relay servers when direct peer-to-peer connections fail, while portmapper handles UPnP and NAT-PMP protocols for automatic port forwarding on supported routers.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →