How S-UI Integrates with sing-box for Proxy Traffic Routing: Core Implementation Guide

S-UI embeds sing-box as its proxy core, bootstrapping a Box instance from JSON configuration to handle all inbound, outbound, and routing logic without implementing its own network stack.

The S-UI project (alireza0/s-ui) provides a web-based management interface for proxy services by leveraging sing-box as its underlying traffic engine. Rather than reinventing network protocols, S-UI acts as a configuration layer that initializes and controls sing-box's native adapters. This integration allows S-UI to support sing-box's full feature set—including multiple inbound protocols, outbound dialers, and sophisticated routing rules—while maintaining a clean separation between the UI and the proxy core.

Core Bootstrapping and Registry Initialization

Before handling traffic, S-UI establishes a global context containing sing-box component registries. In core/main.go, the NewCore() function creates registries for Inbound, Outbound, Endpoint, DNS Transport, and Service components, storing them in a context via sb.Context(...) (lines 33-36). This registry pattern allows sing-box to dynamically instantiate protocol handlers based on configuration without hard-coded dependencies.

Configuration Translation and Box Construction

When an administrator starts the service through the web interface, ConfigService.StartCore() in service/config.go (lines 89-99) marshals database entries into sing-box-compatible JSON and passes it to core.Start(). Inside core/main.go (lines 50-61), this configuration unmarshals into a sing-box option.Options struct, which then instantiates the core proxy engine via NewBox(Options{…}). This Box object becomes the central traffic processor for the entire application.

Adapter Wiring and Traffic Routing

The NewBox implementation in core/box.go constructs three critical managers that determine how traffic flows:

  • Inbound Manager: Created via inbound.NewManager (lines 72-78), this handles listeners for protocols like Shadowsocks, VMess, and Trojan.
  • Outbound Manager: Instantiated through outbound.NewManager (lines 75-77), this manages dialers including direct connections, naive proxy, and TUN interfaces.
  • Router: Built by route.NewRouter (lines 95-100), this component evaluates sing-box routing rules against each connection to select the appropriate outbound tag.

The router instance is stored in a global variable and serves as the decision engine for all proxy traffic, ensuring connections reach their intended destinations according to the merged configuration rules.

Runtime Monitoring and Health Checks

S-UI exposes sing-box runtime metrics through dedicated service methods. ServerService.GetSingboxInfo() in service/server.go (lines 36-48) queries the core instance to report running status, uptime, and goroutine statistics. For outbound validation, core.CheckOutbound in core/outbound_check.go (lines 12-40) utilizes sing-box's built-in urltest utility to probe specific outbound tags against target URLs, returning latency measurements or error states for load balancing decisions.

Integration Code Example

// 1. Build the merged configuration (inbounds, outbounds, services, …)
cfg, _ := configService.GetConfig("")        // ServiceConfig gathers DB data

// 2. Start the sing-box core with that configuration
err := configService.StartCore()             // Calls core.Start(cfg)
if err != nil {
    logger.Error("Failed to launch sing-box:", err)
}

// 3. Query the core for runtime info
info := serverService.GetSingboxInfo()
fmt.Printf("sing-box running=%v, uptime=%d s\n", info["running"], info["stats"].(map[string]interface{})["Uptime"])

// 4. Perform an outbound health check (e.g. tag="proxy", url="https://example.com")
result := configService.CheckOutbound("proxy", "https://example.com")
if result.OK {
    fmt.Printf("Latency: %d ms\n", result.Delay)
} else {
    fmt.Printf("Check error: %s\n", result.Error)
}

Summary

  • S-UI embeds sing-box as a library rather than running it as an external process, enabling tight integration through Go function calls.
  • The core.NewCore() function initializes registries that sing-box uses to dynamically instantiate protocol handlers.
  • Traffic routing is handled entirely by sing-box's native Router, configured through S-UI's database-to-JSON translation layer in service/config.go.
  • Runtime health monitoring leverages sing-box's internal urltest implementation via core.CheckOutbound.
  • All inbound listeners and outbound dialers are managed through sing-box's standard inbound.NewManager and outbound.NewManager APIs.

Frequently Asked Questions

Does S-UI implement its own proxy protocols?

No. According to the alireza0/s-ui source code, S-UI relies entirely on sing-box's protocol implementations. It configures sing-box's InboundRegistry and OutboundRegistry during initialization but does not contain native implementations of Shadowsocks, VMess, or other protocols. All traffic encryption and forwarding is handled by the embedded sing-box Box instance.

How does S-UI convert its database settings into sing-box configurations?

The ConfigService in service/config.go aggregates settings from the S-UI database and marshals them into JSON format compatible with sing-box's option.Options struct. When StartCore() is invoked, this JSON configuration passes to core.Start(), which unmarshals it and constructs the sing-box Box. This translation layer allows the web UI to store human-friendly settings while the core receives machine-optimized sing-box syntax.

Can S-UI run multiple sing-box instances simultaneously?

The current implementation uses a singleton pattern for the core. The core.NewCore() function establishes global registries and stores the router in a package-level variable. While the code structure in core/main.go supports creating multiple Box instances, S-UI's service layer (service/config.go) manages a single core pointer, indicating one active sing-box instance at a time.

What happens when an outbound proxy fails in S-UI?

S-UI detects outbound failures through core.CheckOutbound, which uses sing-box's urltest mechanism (implemented in core/outbound_check.go). This method probes the outbound tag with a specified URL and returns latency or error information. The web interface can use these results to mark outbounds as unhealthy or switch routing rules, though the actual routing fallback logic executes within sing-box's native route.NewRouter implementation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →