# How to Contribute to the iroh Project: A Complete Developer Guide

> Learn how to contribute to the iroh project on GitHub. Follow our guide to fork the repo, implement changes, and submit pull requests for a seamless developer experience.

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

---

**To contribute to the iroh project, engage in GitHub Discussions to validate your approach, file a detailed issue, fork the repository, implement changes in the appropriate crate (such as `iroh` or `iroh-relay`), and submit a draft pull request for iterative review.**

The iroh project is a Rust-based peer-to-peer networking stack built on QUIC that provides hole-punching, relay services, and DNS-based discovery. Maintained by n0-computer, this open-source repository follows a structured workflow to ensure high-quality contributions. Understanding the workspace architecture and the standardized process defined in [`CONTRIBUTING.md`](https://github.com/n0-computer/iroh/blob/main/CONTRIBUTING.md) is essential for successfully submitting code that gets merged.

## Understanding the iroh Repository Structure

The iroh repository is organized as a Cargo workspace containing multiple specialized crates. Knowing which crate owns specific functionality helps you place new code correctly and avoid circular dependencies.

### Core Crates and Their Responsibilities

- **`iroh`** – The core library providing hole-punching, connection establishment, and the public API surface. Entry point is at [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs).
- **`iroh-relay`** – Implements relay client and server logic for public relay nodes. Key implementation files include [`iroh-relay/src/server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server.rs).
- **`iroh-base`** – Contains shared types such as `EndpointId` and `RelayUrl` used across the workspace. See [`iroh-base/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/lib.rs).
- **`iroh-dns` / `iroh-dns-server`** – Handles DNS-based address lookup (Pkarr) for endpoint IDs. Logic resides in [`iroh-dns/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-dns/src/lib.rs).

The top-level [`Cargo.toml`](https://github.com/n0-computer/iroh/blob/main/Cargo.toml) defines workspace members, build profiles, and global settings, making it the map for understanding inter-crate dependencies.

## The iroh Contribution Workflow

Contributing to iroh follows a linear, collaborative process designed to catch issues early and maintain code quality.

1. **Discuss** – Start on the project's [Discussions page](https://github.com/n0-computer/iroh/discussions) to clarify requirements or validate your approach before writing code.

2. **File an Issue** – Search existing issues to avoid duplicates. If none exist, create a new issue using the "New issue" button, including a clear description and labels like `feature` or `bug`.

3. **Fork & Clone** – Fork the repository, then clone your fork locally:

   ```bash
   git clone https://github.com/<your-username>/iroh.git
   cd iroh
   ```

4. **Create a Branch** – Use descriptive names that indicate the change scope:

   ```bash
   git checkout -b feat/socket-metrics
   ```

5. **Implement** – Modify code in the appropriate crate (e.g., [`iroh/src/socket/metrics.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/socket/metrics.rs)). Follow Rust documentation conventions, add unit tests alongside implementations, and include integration tests under `iroh/tests/` when applicable.

6. **Open a Draft Pull Request** – Push your branch and open a PR marked as *draft* to signal work-in-progress. The PR template requires a description, breaking change notes, and a checklist covering self-review, documentation, and tests.

7. **Review Cycle** – Respond to reviewer feedback, iterate on the code, and mark the PR as "Ready for review" when stable.

8. **Merge** – Once approved by maintainers, the PR will be merged into the main branch.

## Practical Example: Adding Socket Metrics

To demonstrate how to contribute to the iroh project, consider adding a simple statistic to track active QUIC streams per socket.

### Implementing the Metrics Struct

Create or modify [`iroh/src/socket/metrics.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/socket/metrics.rs) to define the tracking structure:

```rust
/// Tracks basic socket statistics.
#[derive(Default, Debug, Clone)]
pub struct SocketMetrics {
    /// Current number of open QUIC streams.
    pub open_streams: usize,
}

impl SocketMetrics {
    /// Increment the open-stream counter.
    pub fn inc_streams(&mut self) {
        self.open_streams += 1;
    }

    /// Decrement the open-stream counter.
    pub fn dec_streams(&mut self) {
        self.open_streams = self.open_streams.saturating_sub(1);
    }
}

```

### Exposing the Metrics

Add a public accessor in [`iroh/src/socket.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/socket.rs) to allow callers to retrieve metrics:

```rust
impl Socket {
    /// Return a copy of the current metrics.
    pub fn metrics(&self) -> SocketMetrics {
        self.metrics.clone()
    }
}

```

### Writing the Test

Create [`iroh/tests/socket_metrics.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/tests/socket_metrics.rs) to verify functionality:

```rust
#[tokio::test]
async fn test_socket_metrics() {
    let endpoint = iroh::Endpoint::bind().await.unwrap();
    let socket = endpoint.socket(); // hypothetical accessor
    let mut metrics = socket.metrics();

    // Simulate opening two streams.
    metrics.inc_streams();
    metrics.inc_streams();
    assert_eq!(metrics.open_streams, 2);

    // Simulate closing one stream.
    metrics.dec_streams();
    assert_eq!(metrics.open_streams, 1);
}

```

Run `cargo test` to execute the suite and verify your changes compile and pass.

## Key Files Every Contributor Should Know

- **[`CONTRIBUTING.md`](https://github.com/n0-computer/iroh/blob/main/CONTRIBUTING.md)** – The authoritative source for contribution guidelines, PR style requirements, and the review checklist.
- **[`Cargo.toml`](https://github.com/n0-computer/iroh/blob/main/Cargo.toml)** (workspace root) – Defines all workspace members, build profiles, and dependency versions.
- **[`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs)** – The public API surface for the core library; understanding this helps you maintain backward compatibility.
- **[`iroh-relay/src/server.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/server.rs)** – Core relay server implementation; common target for performance or security improvements.
- **[`iroh-base/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/lib.rs)** – Contains shared primitives like `EndpointId` and `RelayUrl` that propagate across crates.

## Summary

- **Start with communication** – Use GitHub Discussions and Issues to align your work with project goals before coding.
- **Respect the architecture** – Place code in the correct crate (`iroh`, `iroh-relay`, `iroh-base`, etc.) to maintain modularity.
- **Write tests** – Include unit tests with your implementation and integration tests under `iroh/tests/`.
- **Use draft PRs** – Open early drafts to gather feedback during development rather than after completion.
- **Follow the checklist** – Adhere to the requirements in [`CONTRIBUTING.md`](https://github.com/n0-computer/iroh/blob/main/CONTRIBUTING.md) to expedite the review process.

## Frequently Asked Questions

### What programming language is the iroh project written in?

The iroh project is written in **Rust** and organized as a Cargo workspace. All contributions must follow Rust documentation conventions and idiomatic patterns as enforced by the project's CI and linting configuration.

### Do I need to open an issue before submitting a pull request?

Yes, you should search existing issues first and create a new one if your change isn't already tracked. For minor fixes or clarifications, starting with a GitHub Discussion is also acceptable. This prevents duplicate work and ensures your approach aligns with maintainer expectations.

### How do I know which crate to modify when contributing?

Consult the repository structure: use **`iroh`** for core P2P networking and hole-punching logic, **`iroh-relay`** for relay server/client functionality, **`iroh-base`** for shared types and primitives, and **`iroh-dns`** for DNS-related address resolution. The top-level [`Cargo.toml`](https://github.com/n0-computer/iroh/blob/main/Cargo.toml) lists all workspace members and their relationships.

### What is the best way to test changes locally before submitting?

Run `cargo test` from the workspace root to execute the full test suite. For faster feedback during development, run `cargo test --package <crate-name>` to target specific crates. Ensure your changes include unit tests in the source files (e.g., [`src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/src/lib.rs)) and integration tests under `iroh/tests/` when testing cross-component behavior.