Skip to content

How swsrs compares

NAT-traversal is a crowded space. Honest mapping of where swsrs fits and when you should use something else.

TL;DR — when to pick swsrs

Reach for swsrs if all of these are true:

  • You need a rendezvous between two parties (initiator + responder), not a "publish my service on a public URL" gateway.
  • You want to self-host on a tiny machine.
  • The party minting sessions has IdP credentials, but the party connecting to the tunnel does not (and shouldn't need to).
  • You want to embed the peer logic in your app rather than ship a separate CLI to your users.

Reach for something else if you want:

  • A public URL exposing your local dev server: ngrok / Cloudflare Tunnel.
  • Reverse-proxy a long-running internal service to the internet: frp / chisel / rathole / boringproxy.
  • Direct peer-to-peer (audio, video, file-transfer at scale): WebRTC + a TURN server.

Closest comparables — self-hostable WS/HTTP tunnels

ToolLangAuthSession modelEmbeddable SDKFootprintLicense
swsrsGoOIDC + scopes on admin, opaque per-slot tokens on dataEphemeral two-slot rendezvousGo + TypeScript~7 MB binaryMIT
wstunnelRustOptional shared secretPoint-to-point port forwardsmallBSD-3
chiselGoSSH-style user/passLong-running reverse-proxysmallMIT
frpGoToken; dashboard authPre-registered servicesmediumApache-2.0
ratholeRustTokenPre-registered servicessmallApache-2.0
boreRustOptional shared secretPoint-to-point port forwardtinyMIT
piping-serverTS/RustNone (path is the credential)Path-based pipesmallMIT
boringproxyGoOIDC-friendlyReverse-proxy gatewaysmallMIT

vs wstunnel

Our explicit inspiration. wstunnel is excellent if you want one side-to-side TCP/UDP forward and you're OK managing a shared secret.

What swsrs adds: orchestrated session lifecycle, an admin API gated by real OIDC (scopes), and per-tunnel tokens you can hand to a peer without granting them anything else. Plus the SDKs — your app speaks the relay protocol directly instead of spawning wstunnel as a child process.

What you give up: wstunnel is more battle-tested and has a richer port-forwarding feature set.

vs chisel

Closest in spirit on the "small Go binary" axis. chisel uses an SSH-style auth model (users in a file, fingerprint pinning). Strong choice if you want long-running reverse-proxy tunnels and a single operator.

What swsrs adds: OIDC + scope-based auth (no users-in-a-file file to manage), session-based ephemeral tunnels, embeddable SDKs.

What you give up: chisel has connection multiplexing built in. swsrs is one TCP/UDP per session by design.

vs frp / rathole

Different shape. frp clients register predefined services with the server at startup; the server then exposes them. Great for "I have a service in my homelab, expose it permanently."

swsrs is rendezvous-shaped: sessions are ephemeral, the two sides are typically dynamic ("this support engineer wants to talk to that customer's probe right now").

vs piping-server

Philosophically closest. piping-server is a brilliant 1-page idea: two HTTP clients meet at a URL and pipe bytes through it.

What swsrs adds: real auth (piping-server treats path as credential), session lifecycle (TTL, peer-wait, reaper), WebSocket framing (not chunked HTTP), and SDKs.

What you give up: piping-server is gorgeously simple.

SaaS alternatives

Not self-hosted, but worth honest comparison:

ServiceWhen it winsWhen swsrs wins
ngrok"Expose my dev server in 30 seconds." Best one-line UX.You control the data path. No vendor lock-in. Cost at scale.
Cloudflare Tunnel"Run my service behind Cloudflare with WAF, DDoS, edge cache." Free tier.You don't want everything routed through Cloudflare; data-residency requirements; SaaS-allergic.
Tailscale FunnelYou're already on Tailscale and want to expose one node publicly.You don't want to put every endpoint on a mesh VPN.
inlets ProLightweight commercial tunnel for k8s ingress.Self-hosting on a single $3/mo VM.

If your scenario is "expose an HTTP service publicly with TLS-at-edge and request inspection," Cloudflare Tunnel is hard to beat — that's not swsrs's sweet spot.

Different model entirely — direct P2P

ApproachWhen it winsWhen swsrs wins
WebRTC + TURNAudio/video, large-scale media, latency-critical. Direct connection when possible.Lower complexity. No SDP/ICE/DTLS stack to operate. Always-relay is fine for your use case.
libp2p circuit relayYou're already on libp2p (IPFS, etc.).Way simpler. swsrs is one binary; libp2p is a framework.

If you find yourself wanting WebRTC, you probably need WebRTC. swsrs is the right choice when the value of a direct peer-to-peer connection isn't worth the NAT-hole-punching complexity.

What swsrs is not trying to be

Worth being explicit. swsrs is not:

  • A web proxy or HTTP gateway (use Caddy, Traefik, Cloudflare).
  • A VPN (use WireGuard, Tailscale).
  • A connection multiplexer (one session, one stream — by design).
  • A media-routing SFU (use mediasoup / LiveKit).
  • A pub/sub or message bus (use NATS / Redis Streams).

It's a two-party rendezvous + opaque byte relay, with proper auth and tiny operational cost. If that's what you need, swsrs is in the sweet spot.

Released under the MIT License.