Architecture Overview
sing-box is a universal proxy platform built on top of the sing networking library. Unlike Xray-core's monolithic design, sing-box delegates protocol implementations to external sing-* libraries and uses Go's context system for dependency injection.
Source: box.go, adapter/, route/, common/, protocol/
Project Structure
sing-box/
├── box.go # Box struct, lifecycle (New/PreStart/Start/Close)
├── adapter/ # Core interfaces (Inbound, Outbound, Router, etc.)
│ ├── inbound/ # Inbound manager & registry
│ ├── outbound/ # Outbound manager & registry
│ ├── endpoint/ # Endpoint manager & registry (WireGuard, Tailscale)
│ └── service/ # Service manager & registry
├── route/ # Router, connection manager, network manager
│ └── rule/ # Rule matching and actions
├── dns/ # DNS client, router, transport manager
│ └── transport/ # DNS transport implementations
├── protocol/ # All proxy protocol implementations
│ ├── vless/ # VLESS inbound/outbound
│ ├── vmess/ # VMess inbound/outbound
│ ├── trojan/ # Trojan inbound/outbound
│ ├── shadowsocks/ # Shadowsocks (single/multi/relay)
│ ├── hysteria2/ # Hysteria2
│ ├── tuic/ # TUIC
│ ├── tun/ # TUN inbound
│ ├── group/ # Selector, URLTest
│ └── ... # direct, block, dns, socks, http, etc.
├── transport/ # V2Ray-compatible transports
│ ├── v2raywebsocket/ # WebSocket
│ ├── v2raygrpc/ # gRPC (full)
│ ├── v2raygrpclite/ # gRPC (lite, no dep)
│ ├── v2rayhttp/ # HTTP/2
│ ├── v2rayhttpupgrade/ # HTTP Upgrade
│ ├── v2rayquic/ # QUIC
│ └── wireguard/ # WireGuard device/stack
├── common/ # Shared utilities
│ ├── dialer/ # Dialer system (default, detour, resolve, TFO)
│ ├── listener/ # TCP/UDP listeners
│ ├── sniff/ # Protocol sniffers
│ ├── tls/ # TLS, uTLS, REALITY, ECH, kTLS, ACME
│ ├── mux/ # Multiplex client/router
│ └── ... # redir, process, geoip, geosite, etc.
├── option/ # Configuration types
├── include/ # Build tag inclusion
├── experimental/ # Clash API, V2Ray API, cache file, libbox
├── log/ # Logging system
├── constant/ # Constants and enums
└── service/ # External service implementations (CCM, OCM, DERP, etc.)Key Dependencies
| Package | Purpose |
|---|---|
sagernet/sing | Core networking library: N.Dialer, buf.Buffer, M.Socksaddr, bufio |
sagernet/sing-vmess | VLESS + VMess protocol implementation |
sagernet/sing-shadowsocks | Shadowsocks AEAD |
sagernet/sing-shadowsocks2 | Shadowsocks 2022 |
sagernet/sing-shadowtls | ShadowTLS protocol |
sagernet/sing-mux | Multiplex (smux-based) |
sagernet/sing-quic | QUIC-based protocols (Hysteria2, TUIC) |
sagernet/sing-tun | TUN device + IP stack |
sagernet/gvisor | Userspace TCP/IP stack |
sagernet/quic-go | QUIC implementation |
metacubex/utls | uTLS fingerprinting |
sagernet/wireguard-go | WireGuard implementation |
sagernet/tailscale | Tailscale integration |
miekg/dns | DNS message parsing |
anytls/sing-anytls | AnyTLS protocol |
High-Level Data Flow
┌─────────────────────────────────────────────────────────┐
│ Box │
│ │
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │ Inbound │───→│ Router │───→│ Outbound │ │
│ │ Manager │ │ │ │ Manager │ │
│ └──────────┘ │ matchRule│ └───────────────┘ │
│ │ │ sniff │ │ │
│ │ │ resolve │ │ │
│ ▼ └──────────┘ ▼ │
│ ┌──────────┐ │ ┌───────────────┐ │
│ │ Protocol │ ┌────┴────┐ │ Protocol │ │
│ │ Inbound │ │ DNS │ │ Outbound │ │
│ │(decode) │ │ Router │ │ (encode) │ │
│ └──────────┘ └─────────┘ └───────────────┘ │
│ │ │ │
│ ┌────┴────┐ ┌─────┴──────┐ │
│ │ DNS │ │ Connection │ │
│ │Transport│ │ Manager │ │
│ │ Manager │ │ (copy loop)│ │
│ └─────────┘ └────────────┘ │
└─────────────────────────────────────────────────────────┘Connection Flow
- Inbound accepts connection (TCP) or packet (UDP)
- Inbound decodes protocol header, extracts destination
- Inbound calls
router.RouteConnectionEx(ctx, conn, metadata, onClose)orRoutePacketConnectionEx - Router enriches metadata: process info, neighbor info, FakeIP lookup, reverse DNS
- Router iterates rules in order, executing actions:
sniff— peek at data to detect protocol/domainresolve— DNS resolve domain to IPsroute— select outbound (terminal action)reject— drop connection (terminal action)hijack-dns— handle as DNS query (terminal action)bypass— bypass routing (terminal action)
- Router selects outbound based on matched rule (or default)
- Connection trackers wrap the connection (stats, Clash API)
- If outbound implements
ConnectionHandlerEx, it handles directly - Otherwise, ConnectionManager dials remote and runs bidirectional copy
Design Principles
Library delegation: Protocol implementations live in
sing-*libraries. sing-box is the orchestration layer.Context-based DI: All services are registered in context via
service.ContextWith[T]()and retrieved viaservice.FromContext[T](). No global singletons.Direct connections: Unlike Xray-core's Pipe-based Reader/Writer model, sing-box passes
net.ConnandN.PacketConndirectly through the pipeline. This enables zero-copy operations and splice/sendfile.Action-based routing: Rules produce actions, not just outbound tags. This allows sniffing and DNS resolution to be part of the rule chain.
4-phase lifecycle: Components start in phases (Initialize → Start → PostStart → Started) to handle complex dependency ordering without explicit dependency graphs.
Extensible registries: Inbound, outbound, endpoint, DNS transport, and service types are all registered via type registries, making it easy to add new protocol types.