How Shrooms compares

Asked on a livestream: "this is not new and there is no magic — just existing protocols layered over each other."

That is correct and worth conceding first. WireGuard carries the traffic. Path selection is ICE's idea. Reflexive addresses are STUN's. Credentials are ed25519, relays are the TURN pattern, gossip is libp2p's. There is no new cryptography and no new protocol here, and a claim otherwise would be trivial to falsify.

The claim is about a component that is absent, not one that is new.

The table

ShroomsTailscaleNebulaZeroTierYggdrasilWireGuard alone
Coordination servicenoneTailscale's (or self-host Headscale)lighthouses you runroot servers ZeroTier runs; moons self-hostablenonenone
Who can see your topologynobodyTailscale, or you if self-hostedyouZeroTier, or you with moonsnobodyyou
Data planeWireGuardWireGuardNoise (own protocol)own L2 overlayown encrypted IPv6 routingWireGuard
Peer discoverypublic gossip bus (Waku), rendezvous onlycoordination serverlighthousesroots/controllerlink-local + configured peersmanual config
Traffic transits other membersnonononoyes — it is a routing meshno
NAT traversalyesyes, best in classyesyesvia peersno
Relay fallbackdiscovered from its own announceDERP, run by Tailscalerelays you configureroots/moonsinherent to routingnone
Addressingderived from device keyassigned by coordinatorassigned in certassigned by controllerderived from public keymanual
Membershipcredential signed by an admin keySSO/OIDC identityCA-issued certificatecontroller authorisesopen networkwhoever holds a key
Revocationsigned, gossiped, re-announced, survives restartvia coordinatorblocklist (documented gap)via controllern/aremove the peer by hand
Admin key locationa machine that can be offthe coordinatoryour CA machinethe controllern/an/a
MobileAndroid (full peer)iOS + AndroidiOS + AndroidiOS + AndroidAndroidvia app configs
Maturityprototypeproduction, large scaleproductionproductionmatureproduction

The closest thing to this: Nostr VPN

mmalmi/nostr-vpn deserves its own section rather than a column, because it is the same idea reached independently — and its author's stated motivation is ours almost word for word: "Got annoyed by Tailscale requiring 3rd party accounts, so created Nostr VPN."

Read from its README and docs/protocol.md on 2026-08-20, not from summaries:

ShroomsNostr VPN
coordination servicenonenone
signalling substrateLogos Delivery (Waku)Nostr relays
how much rides itcontinuous announces, every 45senrolment and roster delivery only
data planewireguard-go, userspaceFIPS, a Rust WireGuard
identityed25519 device keyNostr keypair (npub)
addressingderived from the device key, IPv6 /48derived: SHA256(network_id + "\n" + pubkey) → 10.44.x.y/32
membershipadmin-signed credential, expiresadmin-signed roster, from a signed join request
revocationsigned, gossiped, re-announced each epoch, survives restartnot documented
relay fallbacka peer that announces itself as one"through FIPS neighbors when direct UDP is blocked"
platformsLinux, AndroidmacOS, Linux, Windows, Android, iOS, StartOS/Umbrel

Where they are ahead

iOS, which we have declared out of scope (ADR-022). The reason is worth understanding rather than resenting: our blocker was never WireGuard, it was fitting a libp2p node inside a Network Extension's memory limit. Nostr signalling is websockets to a relay, which costs almost nothing, so the constraint that stopped us does not apply to them. That is an argument about substrate, not effort.

Platform coverage generally, and release cadence — eleven releases in seven days at one point.

Where the designs genuinely differ

How much depends on somebody else's infrastructure. This is the one where a casual reading would get it backwards. We announce continuously over a public Waku fleet; they use Nostr relays for enrolment and roster delivery only, with peer discovery delegated to the FIPS layer. Their protocol document is explicit that it "should not publish or consume its old Nostr relay peer announcements." So in steady state they lean on third-party infrastructure less than we do, not more — and the outage on 2026-08-20, when five of six Waku entry nodes refused connections and a restarted node could not rejoin, is exactly the class of failure that buys. ADR-031 is our answer to it.

Address space. Both derive addresses from keys, which removes the allocator. Theirs lands in 10.44.0.0/16 through two modulo-254 bytes — about 64,500 possible addresses, so collisions become likely somewhere in the low hundreds of devices by the birthday bound. Ours is a 64-bit interface identifier inside a derived /48, where a collision is not a thing that happens. For a personal mesh neither matters; it is a difference in what the design will tolerate later.

Revocation. Ours is built and deliberate: signed by the authority, gossiped, repeated each epoch and when a peer appears, persisted across restarts, and bounded by an expiry the revocation itself carries (ADR-018). Theirs may exist; it is not in the README or the protocol document, and we have not read the source. "Not documented" is the honest claim, not "absent".

The honest summary

Two projects, the same objection to Tailscale, the same shape of answer, and different substrates underneath. They are further along as a product. We have thought harder about what happens after somebody is admitted — expiry, revocation, per-device credentials — and they have thought harder about being installable on the machine somebody actually owns.

Neither of those is a moat, and it would be silly to pretend otherwise.

What is actually distinctive

Nobody runs a service. Tailscale operates a coordination server; Nebula needs lighthouses you keep alive; ZeroTier has roots. In every case some host knows the membership and topology, and forming new connections depends on it. Shrooms uses a public gossip network for rendezvous only, so there is no account, no control plane, and no host whose disappearance takes the network with it.

Rendezvous is not on the data path. Once tunnels exist, the gossip bus can vanish and traffic keeps flowing — demonstrable by killing it live. In a coordinator design, existing tunnels also survive an outage, but the coordinator still saw the whole graph while it was up. Here nothing ever did.

The authority is off the always-on machine. The admin key lives on a laptop or a smartcard, not on the relay. The relay — the one permanently online box — has no power over membership at all, which is why it can be a €4 VM that gets deleted afterwards. Most overlays put authority and uptime on the same host.

Addresses come from keys. Shared with Yggdrasil and cjdns, and it removes an allocator: nothing to assign, nothing to collide, no state to lose.

Where Shrooms loses

Worth stating plainly, since the point of this page is credibility.

The honest positioning

Every part is old. The combination is not common: a WireGuard data plane, no coordinator, revocable credential membership, key-derived addresses, and a phone that is a full peer rather than a viewer.

And the work was never in inventing a protocol. It was in the constraints — the iOS memory limit, a wire format flag day, a conntrack deadlock between two NATs — because those are the pressures that make a project quietly grow a coordination server. Not growing one is the contribution.