#10877·syncthing

Add iroh connection backend

Author: infogulchCreated Sep 7, 2026Updated Sep 8, 2026
Labelsenhancementneeds-triage

Feature description

I think it would be neat if syncthing supported iroh as another BEP connection backend.

iroh is an open-source library for dial-by-key instead of ip:port. It manages hole-punching, falls back to a relay, and performs automatic migration, without exposing a TCP/QUIC port. The implementation could use the go-iroh port instead of importing/linking rust. There is a public relay pool hosted by the authors of iroh for testing purposes, or relays can be self hosted.

Syncthing has dedicated quite some effort to weave together the tech to deliver reliable peer-to-peer connections on top of the solid sync protocol and UI. Iroh specializes in abstracting the peer to peer connections piece, and I suspect it would be a good fit for syncthing.

I used an agent to write a sample implementation of this feature this which is published on my fork. Expand this details section for an overview.

The code is available at: https://github.com/infogulch/syncthing/commits/iroh-connector

Landed as three commits:

  • lib/connections: add iroh transport
  • gui, api: accept iroh:// URLs as device identity paste
  • test: two-instance sync over iroh only

Highlights:

  • A new BEP transport beside TCP, QUIC, and Syncthing relays, using iroh so two devices can connect by endpoint ID
  • Listen address: iroh://listen
  • Stored address: iroh://<endpoint-id>
  • Share address: iroh://<endpoint-id>?device=<deviceID> (syncthing device ID + iroh locator together)
  • Options:
    • irohRelays: none, n0 defaults (meant for testing, not production), or a list of https addresses
    • connectionPriorityIroh, default 35 (between TCP WAN 30 and QUIC WAN 40)
  • Still Syncthing TLS/BEP on the stream (syncthing/bep/1)
  • Optional noiroh build tag
  • GUI: show/copy/QR the paste URL on the local device ID dialog; accept that URL when adding a device.
  • REST: GET /rest/svc/deviceid?id=iroh://… returns {id, address}

Attribution for clarity: This issue was 100% written by me, and the idea was mine. The implementation prompt was "Deliver the feature described at feature-request-iroh-connector.md with design/review/impl passes as needed until its done." The feature request file was written by an agent over multiple revisions until I was satisfied.

Problem or use case

  • Simplifies the connection process: copy one iroh:// uri from each computer to the other: this is already enough to make the connection
  • Helpful for devices with no stable IP/port (CGNAT, phones, no UPnP)
  • May or may not work better than existing backends in practice. I have not investigated deeply. Local resource usage, routing efficiency, and connection setup latency at least would be interesting to compare.

Alternatives or workarounds

  • Iroh integration based on go-iroh (this issue & my fork)
  • Iroh integration based on importing the rust library
  • tailcat is similarly connect-by-key without a tailnet, but doesn't fit the connection model as well
  • Using a full overlay network like normal Tailscale works today but requires a tailnet