Tailscale — Dependencies#

Module info#

  • Module: tailscale.com
  • Go version: 1.26.1
  • Direct dependencies: 145
  • Indirect dependencies: 344 (total in go.mod: 489)
  • go.sum entries: 1794 (≈ 897 unique module versions, each listed twice for mod + zip hashes)

Dependency categories#

Core infrastructure#

DependencyPurpose
github.com/peterbourgon/ff/v3Flag and config parsing for tailscaled; flags can be set from environment variables or files
go.uber.org/zapStructured logging (used in Kubernetes operator and some sub-systems)
github.com/go-json-experiment/jsonNext-generation JSON encoding (40+ non-test usages); Brad Fitzpatrick is a primary author — Tailscale uses this as a drop-in for encoding/json with richer semantics
github.com/tailscale/hujsonHuJSON (JSON with comments/trailing commas) for config files like acl.json
github.com/creachadair/taskgroup / mds / msyncStructured concurrency (taskgroup), data-structure utilities, and sync primitives from a dependency author closely associated with core Tailscale engineering
github.com/dsnet/trytry.E / try.F helper for error handling — lets deeply nested functions propagate errors without explicit if err != nil chains
github.com/fsnotify/fsnotifyFile system notification for config reload and inotify integration
github.com/tailscale/depawareTailscale’s own tool to track and snapshot dependency graphs; depaware.txt files in cmd/tailscale/ and cmd/tailscaled/ capture exact transitive imports
github.com/tailscale/setecSecret management service client (Tailscale internal secrets infrastructure)

Networking / WireGuard / NAT traversal#

DependencyPurpose
github.com/tailscale/wireguard-goTailscale’s fork of wireguard-go; the core WireGuard userspace implementation. Tailscale maintains this fork to backport fixes, add their own TUN abstractions, and integrate with their netstack mode
golang.zx2c4.com/wintunWindows TUN driver by WireGuard’s author Jason Donenfeld; enables WireGuard on Windows
golang.zx2c4.com/wireguard/windowsWindows-specific WireGuard support library
github.com/miekg/dnsFull-featured DNS library used in Tailscale’s MagicDNS resolver and DNS fallback logic
github.com/huin/goupnpUPnP/IGD for NAT-PMP traversal — discovers and programs consumer routers to open ports
github.com/inetaf/tcpproxyinet.af TCP proxy library for HTTPS/SNI-based routing in the Tailscale ingress proxy
github.com/coder/websocketWebSocket used in the DERP server’s HTTP upgrade path
github.com/mdlayher/netlink / genetlink / socketLow-level Linux netlink socket access for kernel network configuration
github.com/jsimonetti/rtnetlinkLinux routing table manipulation via rtnetlink
github.com/tailscale/netlinkTailscale’s fork of vishvananda/netlink with additional patches
github.com/coreos/go-iptablesiptables rule management on Linux
github.com/google/nftablesnftables for modern Linux firewall rule management (kernel 4.9+)
github.com/vishvananda/netnsLinux network namespace management
github.com/cilium/ebpfeBPF programs for the xdpderper DERP server variant that processes WireGuard packets in the kernel via XDP
github.com/insomniacslk/dhcpDHCP server/client for Tailscale’s subnet router and exit node scenarios
golang.org/x/netExtended Go networking — notably golang.org/x/net/dns/dnsmessage for low-level DNS wire-format parsing
github.com/pires/go-proxyprotoPROXY protocol (HAProxy protocol) support for proxied connections
go4.org/netipxExtended IP address types beyond net/netipIPRange, IPSet, IPPort with set operations
github.com/gaissmai/bartBinary Art Routing Table — highly efficient longest-prefix match IP routing table used in Tailscale’s packet routing
github.com/akutz/memconnIn-memory net.Conn pairs used extensively in tests to simulate network connections
github.com/prometheus-community/pro-bingICMP ping for the prober subsystem that monitors DERP and relay health
github.com/kortschak/wolWake-on-LAN packet construction

Security / Cryptography#

DependencyPurpose
github.com/tailscale/golang-x-cryptoTailscale’s fork of golang.org/x/crypto — extends it with the Noise protocol implementation used in DERP’s encrypted relay handshake
golang.org/x/cryptoStandard Go extended crypto (chacha20poly1305, curve25519, blake2s, etc.)
github.com/hdevalence/ed25519consensusEd25519 in “consensus mode” (ZIP 215 specification) — used in TKA (Tailscale Key Authority) where signature verification must be deterministic across implementations
github.com/fxamacker/cbor/v2CBOR binary serialization for TKA Authority Update Messages (AUMs), where compact wire format and deterministic encoding matter
github.com/google/go-tpmTPM 2.0 client for hardware device attestation and posture reporting
github.com/alexbrainman/sspiWindows Security Support Provider Interface for Windows authentication integration
software.sslmate.com/src/go-pkcs12PKCS#12 certificate bundle handling for Windows certificate store integration
filippo.io/mkcertLocal TLS certificate generation for development and internal services
gopkg.in/square/go-jose.v2JOSE/JWT library used in the tsidp (Tailscale Identity Provider / OIDC) command
filippo.io/edwards25519Low-level Edwards25519 curve arithmetic backing ed25519consensus
github.com/tailscale/certstoreCross-platform access to OS certificate stores (macOS Keychain, Windows cert store)
github.com/tailscale/peercredUnix socket peer credential extraction (UID/GID of connecting process) for local IPC authentication
github.com/tailscale/wfWindows Filtering Platform bindings — used to implement firewall rules at the Windows kernel level
github.com/gorilla/csrfCSRF protection for the local web client served by tailscaled

Data / Storage / Routing#

DependencyPurpose
github.com/hashicorp/raftRaft consensus algorithm — used in the Kubernetes operator for leader election among replicated operator instances
github.com/hashicorp/raft-boltdb/v2BoltDB-backed Raft log store
go.etcd.io/bboltBoltDB embedded key-value store (used via raft-boltdb)
github.com/axiomhq/hyperloglogHyperLogLog cardinality estimation for counting unique peer connections at scale
github.com/jellydator/ttlcache/v3TTL-based in-memory cache with generic type parameters
github.com/golang/groupcacheDistributed singleflight/LRU cache (used in control client to deduplicate concurrent fetches)
github.com/klauspost/compressMulti-format compression (zstd, gzip, deflate, s2) for log transport and storage
github.com/andybalholm/brotliBrotli compression for HTTP responses in internal services
github.com/golang/snappySnappy compression used in log encoding

Observability#

DependencyPurpose
github.com/prometheus/client_golangPrometheus metrics exposition — Tailscale exposes /metrics from tailscaled
github.com/prometheus/commonPrometheus utility types and expfmt
github.com/prometheus/prometheusDirect Prometheus import used in the proxy-to-grafana tool and prober subsystem for remote write
go.uber.org/zap / github.com/go-logr/zaprZap structured logging used in the Kubernetes operator (which follows controller-runtime’s logr interface)

Kubernetes (k8s-operator)#

DependencyPurpose
k8s.io/api / apimachinery / apiserver / client-goFull Kubernetes API client stack for the k8s-operator
sigs.k8s.io/controller-runtimeKubebuilder/controller-runtime framework for building the Kubernetes operator
sigs.k8s.io/controller-toolsCRD schema generation from Go struct annotations
helm.sh/helm/v3Helm client library used in operator to deploy Helm charts
sigs.k8s.io/kindKinD for integration testing the operator against a local Kubernetes cluster
github.com/elastic/crd-ref-docsGenerates API reference docs from CRD definitions
k8s.io/apiextensions-apiserverCRD validation and registration

Cloud / Platform integration#

DependencyPurpose
github.com/aws/aws-sdk-go-v2 (core + S3, SSM, EC2 IMDS, STS)AWS integration: S3 for log storage, SSM for secrets, EC2 IMDS for cloud environment detection
github.com/coreos/go-systemdsystemd journal and unit management for Linux daemon integration
github.com/mdlayher/sdnotifysd_notify protocol to signal readiness to systemd
github.com/godbus/dbus/v5D-Bus for Linux desktop integration (network manager notifications, etc.)
github.com/gokrazy/gokrazygokrazy is a Go-only embedded Linux distribution; Tailscale supports running as a gokrazy appliance for Raspberry Pi/embedded router use cases
github.com/gokrazy/breakglass / serial-busybox / gokrazy-kernelgokrazy ecosystem components for the Tailscale appliance build
github.com/digitalocean/go-smbiosSMBIOS/DMI table reading for hardware posture reporting
github.com/dblohm7/wingoesWindows helper library for COM/process management
github.com/go-ole/go-oleWindows OLE/COM automation

SSH / File sharing (Tailscale SSH / Drive)#

DependencyPurpose
github.com/pkg/sftpSFTP server implementation for Tailscale SSH’s file transfer capability
github.com/bramvdbogaerde/go-scpSCP for scripted file copy in tests and SSH tooling
github.com/creack/ptyPTY allocation for the SSH server (attaches shell sessions)
github.com/anmitsu/go-shlexShell tokenization for parsing SSH command strings
github.com/studio-b12/gowebdavWebDAV client used in Tailscale Drive (file sharing over WebDAV protocol)
github.com/kballard/go-shellquoteShell quoting for constructing safe command strings
github.com/tailscale/goexpectExpect-style terminal interaction for SSH integration tests

Testing#

DependencyPurpose
github.com/frankban/quicktestTailscale’s preferred test assertion library — lighter than testify, chainable qt.Check / qt.Assert with go-cmp integration
github.com/google/go-cmpDeep struct comparison with custom comparers; heavily used for tailcfg type comparison in tests
github.com/stretchr/testifyAlso present (some packages use it), but quicktest is preferred
github.com/google/go-tpmTPM emulator used in attestation tests

Build toolchain (in go.mod as direct deps)#

DependencyPurpose
github.com/golangci/golangci-lintLinting — pulled as a module dep so go run github.com/golangci/golangci-lint/cmd/golangci-lint uses a pinned version
honnef.co/go/toolsstaticcheck static analysis
github.com/goreleaser/nfpm/v2Package building (.deb, .rpm) for Linux distribution
github.com/evanw/esbuildJavaScript bundler used to compile TypeScript web UI assets (cmd/tsconnect)
github.com/tc-hib/winresWindows resource embedding (version info, manifests) into .exe files

UI / Desktop#

DependencyPurpose
fyne.io/systraySystem tray icon management for the Linux/Windows systray binary
github.com/skip2/go-qrcodeQR code generation for pairing / displaying node keys
github.com/atotto/clipboardClipboard access for copying node keys/auth URLs
github.com/toqueteos/webbrowserOpens the default browser for OAuth / admin console flows
github.com/mattn/go-colorable / go-isattyTerminal color detection (used in CLI output)
github.com/Kodeworks/golang-image-icoWindows .ico file generation for the system tray
github.com/fogleman/gg2D graphics for rendering tray icons

gVisor (userspace networking)#

DependencyPurpose
gvisor.dev/gvisorGoogle’s gVisor userspace network stack — Tailscale’s “netstack” mode embeds a complete TCP/IP stack in user space, enabling Tailscale to run without kernel TUN support (useful in containers, CI environments, and as a library). This is one of the largest single dependencies by code size

Stdlib reliance#

Tailscale is deeply stdlib-first. Counting import occurrences across all non-vendor .go files:

PackageOccurrences
fmt591
context422
strings393
time370
errors358
os303
net/netip274
io264
net258
net/http245
bytes232
sync211
encoding/json208
log179
slices149

Key stdlib choices:

  • net/netip (274 usages): Tailscale was an early and major adopter of net/netip (the new Go 1.18 IP address types). Brad Fitzpatrick, who designed net/netip, works at Tailscale, and the package was motivated in part by Tailscale’s needs. The codebase uses netip.Addr, netip.Prefix, and netip.AddrPort pervasively rather than net.IP.
  • slices: Heavy use of the Go 1.21 slices package (149 occurrences) indicates a modern Go mindset.
  • Stdlib crypto: crypto/ed25519, crypto/sha256, crypto/tls, and crypto/rand appear throughout — third-party crypto is only used where stdlib doesn’t reach (Noise protocol, BLAKE2s, CBOR).
  • No third-party logging at the core: The core types/logger package wraps a simple func(string, ...any) type, not any third-party logging framework. zap appears only in Kubernetes operator code where controller-runtime mandates logr.

Shared dependencies#

Dependencies that Tailscale shares with many other projects in the 50-project set — these are cross-cutting connection points:

DependencyShared with
github.com/prometheus/client_golang~29 projects — near-universal Go metrics standard
github.com/google/go-cmp~25 projects — widely used deep comparison in tests
golang.org/x/crypto / net / sync / sysNear-universal (x/ packages are ubiquitous)
github.com/miekg/dnscaddy, consul, grafana, istio, k3s, minio, nomad, traefik, vault — networking projects share DNS needs
k8s.io/client-go~15 projects with Kubernetes integration (argo-cd, dapr, helm, istio, etc.)
github.com/stretchr/testify~30+ projects
github.com/klauspost/compressrclone, minio, grafana, and many others for compression
gvisor.dev/gvisorRare outside Tailscale — only a few projects (moby/Docker) share this heavyweight dep
github.com/hashicorp/raftconsul, nomad, vault — the HashiCorp distributed systems cluster

Vendoring#

No vendor directory. Tailscale relies on the Go module proxy and go.sum checksums. Despite the large dependency count (489 in go.mod, ~897 module versions in go.sum), they chose not to vendor, likely because:

  1. The depaware.txt snapshot files in each binary’s directory already provide a human-readable record of what’s included and serves as a canary for unexpected dependency additions (enforced via deps_test.go).
  2. Vendoring 897 modules would balloon the repository size significantly.
  3. Tailscale controls its most critical dependencies by maintaining its own forks (wireguard-go, golang-x-crypto, netlink, go-winio), reducing the risk of upstream supply-chain surprises.

Notable dependency decisions#

1. Fork-critical, module-proxy the rest. Tailscale maintains 8+ forks of upstream packages (wireguard-go, golang-x-crypto, netlink, go-winio, peercred, xnet, etc.). For packages where correctness is security-critical or where Tailscale needs to move faster than upstream, they fork. For everything else, they use the module proxy. This is a deliberate middle ground between full vendoring and pure upstream dependency.

2. go-json-experiment/json as a bet on the future. Brad Fitzpatrick co-designed this package as the proposed replacement for encoding/json in a future Go version (tracking issue golang/go#71497). Tailscale adopting it in production with 40+ usages is both a dogfooding exercise and a signal of their confidence in the design.

3. net/netip everywhere. The netipx package extends net/netip with IPRange, IPSet, and set algebra operations not in stdlib. Tailscale holds go4.org/netipx as a direct dep and uses it pervasively alongside net/netip. This pairing represents the “full Tailscale IP algebra” that predates (and influenced) the stdlib addition.

4. Toolchain deps in go.mod. golangci-lint, staticcheck (honnef.co/go/tools), nfpm, esbuild, and several other build tools are listed as direct go.mod dependencies with no // indirect. This means developers run go run github.com/golangci/golangci-lint/cmd/golangci-lint at a pinned version rather than installing tools separately — a clean reproducibility approach but one that inflates the go.sum significantly.

5. gVisor as a userspace networking library. Importing gvisor.dev/gvisor pulls in Google’s entire OS kernel sandbox as a library for its TCP/IP stack. This is architecturally extraordinary: Tailscale’s “netstack” mode runs a complete layer-3/4 stack in user space, enabling operation in environments without kernel TUN support. The dependency exists because no lighter-weight, production-quality Go userspace TCP/IP stack existed at the time Tailscale adopted it.

6. CBOR for TKA. The choice of CBOR over JSON/protobuf for TKA (Authority Update Messages) is deliberate: CBOR is both compact and has a canonical encoding form (CBOR Deterministic Encoding) required for cryptographic signing. Protobuf’s canonical encoding is more complex; JSON’s is not standardized. CBOR gives a well-specified byte sequence to sign.

7. Minimal logging framework. The core daemon avoids structured logging frameworks. tailscale.com/types/logger is simply type Logf func(format string, args ...any) — a function type that can be composed, wrapped, and injected. This design means every subsystem can receive a contextual logger without depending on a third-party logging package.