Dart package over Go tsnet

Use a Tailscale node from Dart.

package:tailscale embeds upstream Go tsnet and exposes Dart APIs for lifecycle, nodes, HTTP, TCP, UDP, TLS, Serve, Funnel, routing controls, and diagnostics.

  • ts.http.bind()private HTTP listener
  • ts.tcp.bind()raw streams
  • ts.serve.forward()existing local server
  • ts.prefs.updateMasked()routing controls
Control plane
Auth, prefs, nodes, whois, diagnostics via tsnet and LocalAPI.
Data plane
Owned listeners use fd-backed streams/datagrams, not localhost proxying.
Platforms
Core networking: macOS, iOS, Android, Linux. Mobile TLS/HTTPS Serve/Funnel remains unqualified.

Feature support

What is implemented today.

This is intentionally explicit. Implemented means there is a typed Dart API and coverage in unit, integration, Headscale, or live Tailscale tests depending on what the feature requires. TLS certificate lookup is disabled upstream on iOS and Android, so tls.bind is explicitly unsupported there. R5 Funnel uses shared ServeConfig rather than ListenFunnel, but mobile HTTPS Serve/Funnel still awaits real-device and sidecar receipts.

Current package surface. Features marked implemented have typed Dart APIs and automated coverage at the tier listed in the repository test docs.

Area Dart API Status Upstream / notes
Node lifecycle init, up(ephemeral), down, logout, status Implemented Backed by embedded tsnet.Server lifecycle, including disposable nodes for CI and tests.
Nodes and identity nodes(), nodeByIp(), whois() Implemented Stable node IDs and LocalAPI identity data for authorization checks.
Outbound HTTP http.client Implemented Standard package:http.Client routed through tsnet.HTTPClient.
Inbound HTTP http.bind(port) Implemented fd-backed request and response bodies; no loopback reverse proxy.
Raw transports tcp, udp, tls.bind Implemented Package-native connections/datagrams over Go-owned tailnet sockets. TCP/UDP are the mobile core; TLS termination is currently desktop/server-only.
Serve and Funnel serve.forward, funnel.forward Implemented One runtime-owned ServeConfig authority forwards an existing loopback server; Funnel is its public visibility mode. The hosted R5 tailnet/swap receipt passed 2026-08-10; mobile remains unqualified.
Tailscale Services N/A Not yet Upstream ListenService is available in the current pin; no Dart wrapper yet.
Routing controls prefs, exitNode Implemented LocalAPI prefs wrappers; live Tailscale coverage for hosted-only behavior.
Diagnostics diag.ping, metrics, derpMap, checkUpdate Implemented Typed diagnostic wrappers with structured error codes. Native-version checks are advisory; upgrades arrive through the package or host app.
Taildrop N/A Not yet Roadmap only; no placeholder API is exported.
Profiles N/A Not yet Roadmap only; multi-profile/account management is demand-gated.
Windows All data-plane APIs Unsupported Needs a Windows-native backend; POSIX fd reactor is not portable.

API examples

Common flows in code.

These snippets use the public package API. The full generated Dart reference is published at /api/.

Examples assume Tailscale.init has already run and await ts.up(...) reached a stable state. TLS and Funnel examples are currently desktop/server-only.

quickstart.dart

Architecture

Upstream semantics, Dart-shaped surface.

A caller-isolate supervisor sends token-qualified control calls through a replaceable worker into a per-lifecycle Go runtime and quarantines a failed or timed-out generation before recovery. High-volume transport I/O uses fd capabilities and a shared POSIX reactor. Forwarding APIs are different by design: they publish a local HTTP server the app already owns. The accepted target plan also specifies Keybay-custodied encrypted node state; that secure storage cutover is in the current source, with upstream log/TLS sidecars outside the encryption boundary. First-party Apple and Android backup integration is present; physical-device custody, policy readback, and sidecar receipts remain.

runtime topology

Go owns Tailscale state

Authentication, WireGuard, ACLs, MagicDNS, DERP, TLS certs, and socket establishment stay inside upstream tsnet. Persistent node state is held in a small authenticated encrypted StateStore under an owner-only directory; Keybay protects the installation key.

Dart owns application shape

Callers work with package-native clients, listeners, datagrams, streams, node objects, prefs, and diagnostics.

Lifecycle fails safe

Startup timeout, worker death, first-Up failure, or an indeterminate publication commit quarantines only the matching native generation and rejects stale events before another worker binds.

Persistent storage fails closed

Missing keys, malformed ciphertext, unsafe paths, interrupted reset markers, and recognized pre-launch plaintext layouts are rejected instead of being treated as a fresh identity.

Owned transports use fds

http.bind, tcp.bind, udp.bind, and tls.bind move data through private fd capabilities and the shared reactor.

Forwarding shares upstream authority

serve.forward and funnel.forward mutate one runtime-owned ServeConfig for existing loopback HTTP servers. Exact handles cannot clear replacements; Shelf handlers can run directly on http.bind.

Install

Package metadata and docs.

Requires Dart 3.12+, Go 1.26+ (or Go 1.25+ with GOTOOLCHAIN=auto), and the native toolchain for the target platform. Core networking is supported today on Android, iOS, macOS, and Linux; see the support table for HTTPS caveats.

dependencies:
  tailscale: ^0.9.0