How to Contribute to the iroh Project: A Complete Developer Guide
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 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 atiroh/src/lib.rs.iroh-relay– Implements relay client and server logic for public relay nodes. Key implementation files includeiroh-relay/src/server.rs.iroh-base– Contains shared types such asEndpointIdandRelayUrlused across the workspace. Seeiroh-base/src/lib.rs.iroh-dns/iroh-dns-server– Handles DNS-based address lookup (Pkarr) for endpoint IDs. Logic resides iniroh-dns/src/lib.rs.
The top-level 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.
-
Discuss – Start on the project's Discussions page to clarify requirements or validate your approach before writing code.
-
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
featureorbug. -
Fork & Clone – Fork the repository, then clone your fork locally:
git clone https://github.com/<your-username>/iroh.git cd iroh -
Create a Branch – Use descriptive names that indicate the change scope:
git checkout -b feat/socket-metrics -
Implement – Modify code in the appropriate crate (e.g.,
iroh/src/socket/metrics.rs). Follow Rust documentation conventions, add unit tests alongside implementations, and include integration tests underiroh/tests/when applicable. -
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.
-
Review Cycle – Respond to reviewer feedback, iterate on the code, and mark the PR as "Ready for review" when stable.
-
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 to define the tracking structure:
/// 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 to allow callers to retrieve metrics:
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 to verify functionality:
#[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– The authoritative source for contribution guidelines, PR style requirements, and the review checklist.Cargo.toml(workspace root) – Defines all workspace members, build profiles, and dependency versions.iroh/src/lib.rs– The public API surface for the core library; understanding this helps you maintain backward compatibility.iroh-relay/src/server.rs– Core relay server implementation; common target for performance or security improvements.iroh-base/src/lib.rs– Contains shared primitives likeEndpointIdandRelayUrlthat 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.mdto 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 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) and integration tests under iroh/tests/ when testing cross-component behavior.
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 →