Table of Contents

Getting started

Add go-iroh to a module, connect two endpoints over loopback, and confirm the toolchain.

This page gets a Go program talking to itself over iroh. It is a five-minute environment check; the real tutorial is Build an echo protocol.

Requirements

go-iroh’s go.mod declares go 1.26, so you need a Go toolchain that can build it. Check yours:

go version

There is no cgo, no C toolchain, and no native library to install. A plain go build is enough.

1. Create a project

mkdir go-iroh-demo
cd go-iroh-demo
go mod init go-iroh-demo

2. Paste the program

Create a file named main.go and paste in the following. It binds two endpoints on loopback and connects one to the other:

package main

import (
	"context"
	"fmt"
	"log"
	"net/netip"

	"github.com/tmc/go-iroh/iroh"
	"github.com/tmc/go-iroh/netaddr"
)

const alpn = "example/hello/1"

func main() {
	ctx := context.Background()
	loopback := netip.AddrPortFrom(netip.IPv6Loopback(), 0)

	server, err := iroh.Bind(ctx, iroh.WithALPNs(alpn), iroh.WithBindAddr(loopback))
	if err != nil {
		log.Fatal(err)
	}
	defer server.Shutdown(ctx)

	accepted := make(chan *iroh.Conn, 1)
	go func() {
		conn, err := server.Accept(ctx)
		if err != nil {
			log.Print(err)
			return
		}
		accepted <- conn
	}()

	client, err := iroh.Bind(ctx, iroh.WithBindAddr(loopback))
	if err != nil {
		log.Fatal(err)
	}
	defer client.Shutdown(ctx)

	addr := netaddr.NewEndpointAddr(server.ID()).WithIP(server.LocalAddr())
	conn, err := client.Connect(ctx, addr, alpn)
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	in := <-accepted
	defer in.Close()

	fmt.Printf("connected to %s over %s\n", conn.RemoteID().Z32()[:8], conn.ALPN())
}

3. Fetch the dependency

go mod tidy

This resolves the two imports and adds github.com/tmc/go-iroh to your go.mod.

4. Run it

go run .

You should see one line naming the server’s endpoint ID and the negotiated ALPN, for example:

connected to 37w49eed over example/hello/1

The first eight characters differ on every run — iroh.Bind generates a fresh secret key when you do not supply one with iroh.WithSecretKey.

What just happened

Next steps

Last updated: 2026-08-20