2026 JUNE 18
Iroh is a pretty cool project by n0 computer. It provides a way for two computers behind NAT to connect. Even though none of them have a stable public IP or open ports in their router. This opens up quite a few possibilities. One of which is running a git server behind NAT on a normal computer. Let your co-workers and friends push directly to your repository. Pull and push from theirs. Turns out git has strong transport abstraction and iroh fits right in. Check it out here:
Game projects can grow quite large. Unfortunately, when repositories grow large GitHub’s size limits kick in. There must be a better way than storing our git repositories without third parties.
Fortunately for us, iroh reached version 1.0 recently and git allows for transport abstractions! With these two pieces we can stream huge git repositories directly to our friends peer-to-peer.
The source code and pre-built binaries are available on GitHub:
Download
the pre-compiled Windows binaries, or compile your own from source. You need
cargo then run
cargo build --release.
Add the binaries to your PATH. This is required for git to find them, and for you to invoke them from the terminal.
The git-iroh binary is used to invoke
git iroh commands for sharing repositories, managing
access, and other chores. Required by both the server and the
client.
The git-remote-iroh binary is used to resolve
iroh:// style URLs when cloning a repository. Technically
only required by the client.
The iroh-git-tray is the long running server that
listens for incoming connections from git-remote-iroh. It
provides a notification icon on Windows and a context menu with creature
comforts such as “Start at login”.
The iroh-git-daemon is the same thing; but in CLI
form.
This is also a good time to update your git installation to the latest version.
Let’s say you want to share the repository at
C:/Repos/MyRepo with your friend. Three things must
happen:
The daemon is the long running server that listens for incoming connections, it facilitates access control, and it hands over incoming push/pull requests to your git installation. It’s a rather dumb pipe that ferries git packets back and forth. But, it will only serve git repositories you have authorized. And, it will only accept connections from members you’ve granted access.
You need to know your friend’s NODE_ID in order to grant them access
to the repository. Iroh doesn’t use IP-addresses. Instead it uses stable
public/private encryption key pairs. A NODE_ID is the public part of
such a key. Each iroh-git client gets one, and each
iroh-git server gets another. Iroh uses these NODE_IDs to
facilitate end-to-end encryption and IP-lookup.
Your friend runs git iroh show-id. This prints their
NODE_ID. Something like this:
$ git iroh show-id
877c36753fcc84f71f9f804010ab4d0941d0a88ab95c1afabc09d93c6be6712cThat NODE_ID is their unique identifier. It belongs to your friend, and them only. This is how they are identified. This is the public part of their cryptographic key.
The NODE_ID isn’t secret. It is the public part of the cryptographic key after all. But only people that possess your NODE_ID can attempt a connection. The NODE_ID is un-guessable, though. Don’t hand them out unnecessarily. They can be regenerated if you need to be forgotten. See
git iroh help keygen.
They hand you their NODE_ID. You grant access to the repository:
$ cd C:/Repos/MyRepo
$ git iroh grant 877c36753fcc84f71f9f804010ab4d0941d0a88ab95c1afabc09d93c6be6712c --write --name friend
granted read-write access to C:/Repos/MyRepo
iroh://tfzuupmqj2mutd66lykmt7u4xstmidaht...eyh64bhxkjgwynbyr5xca/MyRepo.gitThe --write flag grants push access. Without, they can
only pull.
Push or pull access is granted on a per-repository and per-NODE_ID basis. All refs are visible to everyone with access. There is no access control for individual branches.
The --name flag is used to identify them in the list of
shared repositories:
$ git iroh list
C:/Repos/MyRepo [vxlmata73qe65je23buhchw4ia]
rw friend (877c36753fcc84f71f9f804010ab4d0941d0a88ab95c1afabc09d93c6be6712c)The resulting iroh-suffixed URL is used by your friend to clone the repository:
git clone iroh://tfzuupmqj2mutd66lykmt7u...zvs4l5n23aeyh64bhxkjgwynbyr5xca/MyRepo.gitThis URL contains the server’s NODE_ID and a repository ID. The
MyRepo.git part is only there to make
git clone create a MyRepo directory.
The URL is unique per shared repository but only accessible to those you’ve granted access. The system knows your friend’s NODE_ID. It knows which cryptographic key to expect. Unknown NODE_IDs are rejected.
List all repositories you’ve shared with
git iroh list:
$ git iroh list
C:/Repos/MyRepo [vxlmata73qe65je23buhchw4ia]
rw friend (877c36753fcc84f71f9f804010ab4d0941d0a88ab95c1afabc09d93c6be6712c)The vxlmata73qe65je23buhchw4ia is the SHARE_ID for the
repository at C:/Repos/MyRepo. We can stop sharing this
repository with:
$ git iroh stop vxlmata73qe65je23buhchw4ia
# or
$ cd C:/Repos/MyRepo
$ git iroh stop --thisIt is also possible to revoke access for single member:
$ cd C:/Repos/MyRepo
$ git iroh revoke 877c36753fcc84f71f9f804010ab4d0941d0a88ab95c1afabc09d93c6be6712cWhen sharing a repository, I suggest you share a bare
repository. With a bare repository pushes and pulls works as expected.
The one sharing a repository can simply create a new bare repository,
set it as their origin then
git push -u origin master as normal:
$ cd C:/Repos/MyRepoBare.git
$ git init --bare
$ git iroh grant 877c36753fcc...afabc09d93c6be6712c # Share with friend
$ cd C:/Repos/MyRepo
$ git remote add origin C:/Repos/MyRepoBare.git # Yes, a file path!
$ git push -u origin masterThe downside, you now have two repositories on your hard-drive. A redundancy win though!
If instead, you share your checked out repository directly, git throws some nice error messages when your friend tries to push your checked out branch. Probably don’t disable those errors. Instead, either push to a non-checked out branch by following a successful Git branching model (good luck convincing your friend of that ;) Better yet, create a bare repository.
Check out iroh-git on GitHub.