libtailscale runs a full Tailscale node inside your app's own process, so your app can join a private network without anyone installing a VPN. Your app dials peers by name, serves a port and makes HTTP calls across a private network. No system VPN, no VPN entitlement, no permission dialog, no second app.
What it's for
Apps that need private connections between devices: agents, remote control, field equipment. It works with Tailscale or with a self-hosted Headscale server, and only one URL changes.
Why it exists
PRCHD asks every user to install Tailscale on their phone. I'd like it to ask nobody. libtailscale is one way to get there: the network, embedded in the app. I built it before the product needed it, and it's now one of two candidates being tested for PRCHD's managed network. The other is iroh, which needs no control plane. Spikes will decide between them.
Decisions
- A minimal surface, not API parity. Configure, start, observe, connect, listen. UDP, file transfer, SSH and exit nodes are left out on purpose.
- Nothing blocks your app. Blocking native calls run on helper isolates, and one dedicated isolate drives every socket from a single poll loop.
-
Real sockets.
connect()returns a standard DartSocket, so existing HTTP clients, gRPC and WebSockets work unchanged. - A timeout is mandatory, because an unreachable control server produces no error. It just waits forever.
Under the hood
- Bindings to Tailscale's official C library, plus small hand-written libc bindings, so no C shim ships.
- The package ships no binaries. At build time it downloads prebuilt native libraries checked against committed SHA-256 checksums, or builds them from source with a pinned Go toolchain.
- Each platform has its own trick. iOS gets a static archive re-linked as a framework. Android gets 16 KB page alignment, and a patch that lists network interfaces without netlink, which Android 11 and later block.
- Ten native builds per release, from a CI matrix. Integration tests run in CI against an in-process control server, and releases now publish from CI.
- 124 tests.