Remix.run Logo
Show HN: Tt – P2P terminal sharing over WebRTC
10 points by artpar a day ago | 2 comments

Made this to use my laptop terminal session on mobile without data going through a server.

tt start -p mypassword → get a URL (qrcode) → open in browser → enter password → connected.

Direct webrtc datachannel between your machine and browser.

Signaling server is a cloudflare worker, exchanges ~2KB of sdp/ice metadata then gets out of the way. Password never transmitted - argon2id derives 256-bit key locally on both ends. All terminal i/o gets nacl secretbox encryption before hitting the datachannel. double encrypted with dtls underneath but I wanted the relay to see nothing useful even during signaling.

go + pion/webrtc, about 14k loc. browser is xterm.js + webcrypto for argon2id. stun default, turn for symmetric nat.

my use case: checking on claude code runs from my phone when im not at my desk. hotel wifi, spotty mobile data. spent time on turn fallback, keepalive with reconnection, buffered writes during disconnects. pwa so it works from home screen and survives app switching. holds up ok on 3g.

Trade-offs: ice gathering takes 2-5s on connect. browser cant initiate, need cli on host. codes expire 24h.

Single binary, no deps. daemon mode for multiple sessions. tests with race detector, chaos tests for disconnects, network condition simulation. crypto and webrtc at ~72% coverage.

https://github.com/artpar/terminal-tunnel

ps: default relay runs on my cloudflare free tier so no guarantees. you can self-host the worker or run tt relay locally.

Sean-Der a day ago | parent [-]

That's super cool! Nice work.

I love all the 'free stuff' you get with WebRTC. My porch is just on the edge of WiFi/5G and WebRTC (or mosh) feels much nicer.

artpar a day ago | parent [-]

Thanks! And wow, getting a kind word from a Pion maintainer means a lot. Your library made this whole thing possible. The datachannel API is incredibly clean to work with. Appreciate you and the team's work on it.