# How to Create an Iroh Endpoint: Complete Guide to QUIC Peer-to-Peer Networking

> Learn to create an Iroh Endpoint for QUIC peer-to-peer networking. This guide covers managing transport, identity, and NAT traversal with the Iroh Builder pattern.

- Repository: [number zero/iroh](https://github.com/n0-computer/iroh)
- Tags: how-to-guide
- Published: 2026-06-25

---

**An Iroh Endpoint is the central abstraction in the n0-computer/iroh stack that manages QUIC transport, cryptographic identity, and NAT traversal, created using the `Builder` pattern in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs).**

An Iroh Endpoint serves as the primary entry point for all peer-to-peer communication in the iroh networking library. According to the n0-computer/iroh source code, this struct encapsulates the entire QUIC transport layer, handles hole-punching and relay fallback, and manages the cryptographic identity required for secure connections. Understanding how to properly create and configure an Iroh Endpoint is essential for building distributed applications that require direct, encrypted communication between nodes.

## What Is an Iroh Endpoint?

An **Iroh Endpoint** is the core abstraction that drives all peer-to-peer communication in the iroh stack. Located in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs), the `Endpoint` struct encapsulates a QUIC transport built on the **noq** library and manages the complete lifecycle of secure connections.

The endpoint handles several critical functions:

- **Generation or loading of cryptographic identities** (`SecretKey` → `EndpointId`)
- **Discovery of remote peers** via address-lookup services or configured relays
- **Hole-punching, NAT traversal**, and fallback to public relay servers when direct connections fail
- **Lifecycle management** including binding, closing, adding external addresses, and setting ALPNs

According to the implementation at line 896 of [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs), the `Endpoint` struct provides the public API for all networking operations, acting as a singleton per process to maximize performance and resource utilization.

## Iroh Endpoint Architecture and Key Components

### Cryptographic Identity and EndpointId

Each Iroh Endpoint owns a `SecretKey` that determines its `EndpointId`. If no key is supplied during construction, the builder automatically generates a fresh one. This identity mechanism is implemented in the `Builder::bind` method at line 124 of [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs).

### QUIC Transport Layer

The endpoint uses **noq** for encrypted, multiplexed streams. The transport configuration (`QuicTransportConfig`) is established during the builder phase, as seen in `Builder::empty` at line 190. This integration provides the underlying QUIC protocol implementation that powers all iroh communications.

### Relay and NAT Traversal

Optional `RelayMap` and NAT-traversal logic are injected via `RelayConfig`. When direct UDP paths are unavailable, the endpoint automatically falls back to configured relays. This logic is part of the builder initialization in `Builder::empty` at line 190 of [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs).

### Address Lookup Services

The endpoint supports pluggable address-lookup services (such as DNS or PKARR) that resolve an `EndpointId` to reachable addresses. This is configured through the `address_lookup` field in the `Builder` struct.

### ALPN Management

Application-Layer protocol negotiation (ALPN) is managed through `Endpoint::set_alpns` at line 664. This method configures the list of protocols the endpoint will accept for inbound connections, ensuring protocol compatibility with remote peers.

## How to Create an Iroh Endpoint

The n0-computer/iroh library provides two primary approaches for creating an endpoint: using the default preset for quick setup or the builder pattern for custom configuration.

### Quick Creation with DefaultPreset

For most applications, creating an endpoint requires a single line using the `DefaultPreset`:

```rust
use iroh::endpoint::Endpoint;
use iroh::preset::DefaultPreset;

let endpoint = Endpoint::bind(DefaultPreset).await?;

```

This approach, as documented in the library examples, creates a fully functional endpoint with sensible defaults for relay configuration, transport settings, and key generation.

### Custom Configuration Using the Builder Pattern

For production deployments requiring specific keys, static addresses, or custom relay configurations, use the `Builder` struct found at line 129 of [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs):

```rust
use iroh::endpoint::{Endpoint, Builder};
use iroh::preset::DefaultPreset;
use iroh::base::SecretKey;
use std::net::SocketAddr;

// Generate or load your own cryptographic identity
let secret_key = SecretKey::generate();

let endpoint = Builder::new(DefaultPreset)
    .secret_key(secret_key)                          // Set custom identity
    .add_relay("https://relay.iroh.link".parse()?)  // Configure relay server
    .external_addr("203.0.113.10:4000".parse::<SocketAddr>()?) // Advertise static address
    .bind()
    .await?;

```

The `bind` method at line 124 completes the construction and boots the underlying QUIC endpoint, returning a fully initialized `Endpoint` instance.

### Configuring ALPN Protocols

After creation, configure the endpoint to accept specific protocols using `set_alpns`:

```rust
endpoint.set_alpns(vec![b"myproto/1".to_vec()]);

```

This method, located at line 664 of [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs), must be called before accepting connections to ensure the endpoint correctly negotiates application protocols.

## Establishing Connections and Managing Lifecycle

Once created, the endpoint facilitates outgoing connections and manages the lifecycle of active streams:

```rust
// Connect to a remote endpoint using its EndpointId or full address
let remote_addr = "iroh://abcd...".parse()?;
let connection = endpoint.connect(remote_addr, b"myproto/1").await?;

// Open a bidirectional QUIC stream
let (mut send, mut recv) = connection.open_bi().await?;

// Clean shutdown
endpoint.close().await;

```

The `open_bi` method creates bidirectional streams over the QUIC connection, while `endpoint.close()` gracefully terminates all active connections and cleans up resources.

## Summary

- An **Iroh Endpoint** is the central abstraction in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) that manages QUIC transport, cryptographic identity (`SecretKey` → `EndpointId`), and NAT traversal.
- Create endpoints using either `Endpoint::bind(DefaultPreset)` for quick setup or the `Builder` pattern (line 129) for custom configurations including static keys and relay settings.
- The `Builder::bind` method at line 124 initializes the underlying noq-based QUIC transport and returns the fully constructed endpoint.
- Configure accepted protocols using `Endpoint::set_alpns` (line 664) and manage external addresses via `Endpoint::add_external_addr` (line 1008).
- Use `endpoint.close()` for graceful shutdown and resource cleanup.

## Frequently Asked Questions

### What is the difference between an Iroh Endpoint and a connection?

An **Iroh Endpoint** is the long-lived QUIC server/client instance that manages all networking resources, while a connection represents a single session to a specific remote peer. The endpoint handles identity, binding, and multiplexing, whereas connections manage individual streams between two specific nodes.

### Do I need to supply my own SecretKey when creating an Iroh Endpoint?

No. If you do not provide a `SecretKey`, the `Builder::bind` method automatically generates a fresh cryptographic identity. Supplying your own key is only necessary when you need a stable `EndpointId` across restarts or when joining an existing distributed system with predetermined identities.

### How does an Iroh Endpoint handle NAT traversal?

The endpoint implements hole-punching and automatic fallback to relay servers through the `RelayMap` configuration. When direct UDP paths fail, traffic routes through configured relays (set via `Builder::add_relay`), ensuring connectivity even behind restrictive NATs. This logic is initialized in `Builder::empty` at line 190 of [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs).

### Can I create multiple Iroh Endpoints in a single process?

While technically possible, the n0-computer/iroh documentation recommends creating **one** endpoint per process. A singleton pattern allows all outgoing and incoming streams to share the same underlying QUIC session pool, significantly improving performance and reducing resource usage.