# N0 vs Minimal vs Empty Endpoint Presets in Iroh: A Complete Guide

> Understand Iroh's N0, Minimal, and Empty endpoint presets. Learn how each configuration level differs from a blank slate to full production defaults for your P2P applications.

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

---

**The N0, Minimal, and Empty endpoint presets in iroh represent three levels of configuration—Empty provides a blank slate requiring manual setup, Minimal sets only the mandatory crypto provider, and N0 applies full production defaults including PKARR publishing and relay configuration.**

When building QUIC endpoints with the iroh networking library, developers must choose between three distinct configuration strategies. The **N0, Minimal, and Empty endpoint presets** defined in [`iroh/src/endpoint/presets.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/presets.rs) determine how much of the network stack is pre-configured for you. Understanding these presets is essential for balancing control against convenience when establishing peer-to-peer connections.

## What Are Endpoint Presets?

Endpoint presets implement the `Preset` trait, which simply mutates an `Endpoint::Builder` to apply specific configuration defaults. Located in [`iroh/src/endpoint/presets.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/presets.rs), these presets allow you to quickly initialize network endpoints with varying levels of pre-configuration. You apply them using either `Endpoint::builder(presets::Empty)` for manual construction or `Endpoint::bind(presets::Variant)` for immediate binding.

The preset system sits atop the builder architecture defined in [`iroh/src/endpoint/builder.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/builder.rs), offering a type-safe way to ensure mandatory fields like the crypto provider are properly initialized before the endpoint attempts to bind to network interfaces.

## The Three Endpoint Preset Variants

### Empty Preset

The **Empty** preset returns the builder completely unchanged, performing no configuration whatsoever. This provides maximum control but requires you to manually set every mandatory option, particularly the crypto provider.

When using `Endpoint::bind(presets::Empty)`, the operation will always fail because the builder lacks the mandatory `crypto_provider` field. You must instead use `Endpoint::builder(presets::Empty)` and manually configure required fields before calling `.bind()`.

### Minimal Preset

The **Minimal** preset sets the mandatory `Builder::crypto_provider` field to a default TLS crypto provider, ensuring that `Endpoint::bind(presets::Minimal)` succeeds. According to the source code in [`iroh/src/endpoint/presets.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/presets.rs), it selects **Ring** when the `tls-ring` feature is enabled, otherwise falling back to **AWS-LC-RS**.

This preset requires the `with_crypto_provider` feature flag during compilation. It represents the bare minimum configuration needed to establish a functional endpoint, providing just enough defaults to bind without additional network services like PKARR or relays.

### N0 Preset

The **N0** preset starts from the **Minimal** configuration and adds the full suite of "n0" production defaults. As implemented in [`iroh/src/endpoint/presets.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/presets.rs), it configures:

- **PKARR publisher** and DNS address-lookup service pointing at `iroh.link`
- **Relay mode** set to the default relay list (or disabled in the `N0DisableRelay` variant)

This creates a ready-to-use endpoint that communicates with the public N0 network infrastructure. Like Minimal, it requires a crypto-provider feature because it builds upon that preset's foundation.

## Practical Usage Examples

The following examples demonstrate how to instantiate endpoints using each preset variant:

```rust
use iroh::{Endpoint, endpoint::presets};

// Empty preset - requires manual crypto provider configuration
let mut builder = Endpoint::builder(presets::Empty);
builder = builder.crypto_provider(my_custom_provider);
let ep = builder.bind().await?;

// Minimal preset - automatic crypto provider selection
let ep = Endpoint::bind(presets::Minimal).await?;

// N0 preset - full production configuration with PKARR and relay
let ep = Endpoint::bind(presets::N0).await?;

```

## Choosing the Right Preset

Select your preset based on the required level of control and the target environment:

- **Empty**: Use when you need complete control over the crypto provider and all other configuration options, or when integrating with custom TLS implementations.
- **Minimal**: Use for basic peer-to-peer connections that don't require public network discovery or when you want to manually configure relay and PKARR settings separately.
- **N0**: Use for production deployments that need to communicate with the public N0 network, requiring immediate DNS-based address resolution and relay connectivity.

## Summary

- **Empty** provides a blank builder with no mandatory fields set, requiring manual configuration of the crypto provider before binding.
- **Minimal** automatically configures the mandatory crypto provider (Ring or AWS-LC-RS), guaranteeing successful binding while leaving network services unconfigured.
- **N0** extends Minimal with full production defaults including PKARR publishing, DNS lookup services for `iroh.link`, and relay configuration for immediate public network participation.
- All presets except Empty require the `with_crypto_provider` feature flag to compile successfully.

## Frequently Asked Questions

### What happens if I use Empty with Endpoint::bind?

Using `Endpoint::bind(presets::Empty)` will always fail because the Empty preset does not set the mandatory `crypto_provider` field. You must use `Endpoint::builder(presets::Empty)` and manually configure the crypto provider before calling `.bind()`.

### Which crypto provider does the Minimal preset select?

The Minimal preset automatically selects **Ring** when the `tls-ring` feature is enabled, otherwise falling back to **AWS-LC-RS**. This selection happens in [`iroh/src/endpoint/presets.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/presets.rs) and ensures a valid TLS implementation is available for QUIC connections.

### Do I need the with_crypto_provider feature for all presets?

Yes, the `with_crypto_provider` feature is required for both the **Minimal** and **N0** presets because they configure the crypto provider field. The **Empty** preset technically does not require this feature at the preset level, but you will still need to provide a crypto provider manually before the endpoint can bind.

### Can I customize the N0 preset after applying it?

Yes, you can use `Endpoint::builder(presets::N0)` to obtain a pre-configured builder and then modify specific fields before binding. This allows you to start with the N0 defaults (PKARR, relay configuration) and override specific options like custom relay servers or DNS settings while maintaining the base crypto provider configuration.