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

> Learn how S-UI integrates with sing-box for proxy traffic routing. Explore the core implementation, bootstrapping a Box instance, and managing network logic.

- Repository: [Alireza Ahmadi/s-ui](https://github.com/alireza0/s-ui)
- Tags: how-to-guide
- Published: 2026-05-22

---

**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`](https://github.com/alireza0/s-ui/blob/main/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`](https://github.com/alireza0/s-ui/blob/main/service/config.go) (lines 89-99) marshals database entries into sing-box-compatible JSON and passes it to `core.Start()`. Inside [`core/main.go`](https://github.com/alireza0/s-ui/blob/main/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`](https://github.com/alireza0/s-ui/blob/main/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`](https://github.com/alireza0/s-ui/blob/main/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`](https://github.com/alireza0/s-ui/blob/main/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

```go
// 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`](https://github.com/alireza0/s-ui/blob/main/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`](https://github.com/alireza0/s-ui/blob/main/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`](https://github.com/alireza0/s-ui/blob/main/core/main.go) supports creating multiple Box instances, S-UI's service layer ([`service/config.go`](https://github.com/alireza0/s-ui/blob/main/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`](https://github.com/alireza0/s-ui/blob/main/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.