Thank you for your interest in contributing!
- Rust 1.77+ (
rustup update stable) - Node.js 18+ (for Node.js adapter)
- Deno 2+ (for Deno adapter)
- Tauri CLI v2 (for Tauri plugin)
Run once after cloning to enable the pre-commit hook (checks cargo fmt):
git config core.hooksPath .githooks# Check all Rust crates
cargo check --workspace
# Check Tauri plugin (separate workspace)
cd packages/iroh-http-tauri && cargo check
# TypeScript
npm install
npm run typecheck- Rust:
cargo fmt+cargo clippy - TypeScript: standard formatting
Run benchmarks in release mode and on a dedicated machine when possible.
# Node.js (mitata)
npm run bench:node
# Deno (Deno.bench)
npm run bench:deno
# Rust core / Tauri baseline (Criterion)
npm run bench:rustFor normalized benchmark reports used by CI regression checks:
npm run bench:node:report
npm run bench:deno:report- Fork the repository
- Create a feature branch:
git checkout -b feature/my-change - Make your changes with tests
- Run
cargo check --workspaceto verify Rust compiles - Submit a pull request
Do not bump version fields manually. This includes Cargo.toml, package.json, deno.json, and deno.jsonc.
Version fields are managed exclusively by scripts/release.sh, which bumps all manifests atomically, regenerates lock files, prepends the release section to CHANGELOG.md (via git-cliff), and produces a chore: release X.Y.Z commit immediately before tagging and publishing. Bumping versions inside a feature or fix commit breaks CI: the new version's platform binaries don't exist on npm until the tag is published, so npm ci crashes on every platform for the entire window between the bump and the release.
CI enforces this via the version-bump-policy job, which rejects any commit that touches a version-bearing file unless the commit subject starts with chore: release.
The release script uses git-cliff to prepend a curated version section to
CHANGELOG.md. The tag workflow then extracts that reviewed section verbatim
for the draft GitHub Release body; it does not regenerate a second set of raw
notes. This is why commit messages must follow the Conventional Commit rules in
AGENTS.md. git-cliff must be installed locally to cut a release
(brew install git-cliff or cargo install git-cliff); the release script
checks for it up front.
Before running the release script, review the changes since the previous tag. If they materially change mobile discovery implementation, native lifecycle, permissions, service declarations, or setup instructions, complete the affected physical-device matrix in the on-device DNS-SD verification runbook. Deterministic contracts and native compile jobs do not replace this LAN/device test.
Record the exact candidate commit, device models and OS/API versions, tested platform pairs and directions, suite totals, generic DNS-SD result, and the required JSON/log excerpts using the runbook's results template. Link that evidence from the release-tracking issue and resolve or explicitly defer every follow-up before creating the tag.
To cut a release: bash scripts/release.sh X.Y.Z
Pushing the release tag creates a draft GitHub release and starts three independent workflows. It does not publish packages. Complete the release in this order:
- Wait for the tag's Build, Extended tests, and Benchmarks workflows to pass (benchmarks record a snapshot; they do not enforce a performance gate).
- Verify that the draft release assets and the successful Build run use the tag's exact commit SHA.
- Smoke-test the native artifacts produced by that Build run.
- Manually run the Publish workflow with the release tag. It resolves the tag to the successful Build run and promotes those exact artifacts to npm, crates.io, and JSR.
- Verify the published versions and perform a clean consumer install.
- Publish the draft GitHub release.
The release script must be run from a clean local main at the exact
origin/main tip. It pushes only the release commit and its single tag,
atomically; unrelated local tags are never pushed.
Do not publish the GitHub draft or dispatch Publish before all tag workflows are green. If a release is abandoned before any registry package is published, leave the GitHub release as a draft while deciding whether to retry or retire the tag; never reuse its artifacts for a different commit.
By contributing, you agree that your contributions will be licensed under MIT OR Apache-2.0.