# How to Add Custom Protocols to S-UI: A Complete Implementation Guide

> Learn to add custom protocols to S-UI by implementing Go interfaces, registering them in core/register.go, and rebuilding the binary. Integrate your protocols seamlessly.

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

---

**To add custom protocols to S-UI, implement Sing-Box's Inbound and Outbound interfaces in a Go package, register it in [`core/register.go`](https://github.com/alireza0/s-ui/blob/main/core/register.go), and rebuild the binary.**

S-UI is a web interface for the Sing-Box proxy library that requires protocol implementations to satisfy specific adapter interfaces. Adding custom protocols to S-UI involves creating a Go package that integrates with Sing-Box's registry system. This guide references the actual implementation patterns found in the `alireza0/s-ui` repository.

## Understanding the Protocol Architecture

S-UI delegates all network protocol handling to the Sing-Box library. The application maintains a centralized registry in [`core/register.go`](https://github.com/alireza0/s-ui/blob/main/core/register.go) where all inbound, outbound, and endpoint plugins hook into the system. This architecture allows developers to introduce new transport protocols without modifying the React frontend or database schemas, as the UI dynamically populates protocol dropdowns from this backend registry.

## Step 1: Implement the Protocol Package

Create a new Go package that satisfies the **Sing-Box** `Inbound` and/or `Outbound` interfaces. Most custom protocols require both to handle traffic acceptance and routing.

Your package must expose two registration functions that follow the factory pattern used throughout Sing-Box:

- `RegisterInbound(registry *inbound.Registry)` – Registers the protocol for accepting connections
- `RegisterOutbound(registry *outbound.Registry)` – Registers the protocol for routing traffic

Study existing implementations in `github.com/sagernet/sing-box/protocol/` as templates. The VMess protocol registration in [`core/register.go`](https://github.com/alireza0/s-ui/blob/main/core/register.go) demonstrates the exact structure expected by the registry.

## Step 2: Register in core/register.go

Open [`core/register.go`](https://github.com/alireza0/s-ui/blob/main/core/register.go), the central registry file where S-UI aggregates all protocol support.

Add an import for your new package:

```go
import (
    // ... existing imports ...
    "github.com/yourname/sui-myproto"
)

```

Insert registration calls inside the appropriate factory functions. For inbound support, modify `InboundRegistry()`:

```go
func InboundRegistry() *inbound.Registry {
    registry := inbound.NewRegistry()
    // ... existing registrations ...
    myproto.RegisterInbound(registry)  // Add this line
    return registry
}

```

For outbound support, modify `OutboundRegistry()`:

```go
func OutboundRegistry() *outbound.Registry {
    registry := outbound.NewRegistry()
    // ... existing registrations ...
    myproto.RegisterOutbound(registry) // Add this line
    return registry
}

```

If your protocol requires custom endpoint logic (similar to WireGuard), also add the registration call inside `EndpointRegistry()` in the same file.

## Step 3: Rebuild and Restart

Compile the modified source using the standard build script:

```bash
./build.sh

```

Alternatively, build manually:

```bash
go build -o sui main.go

```

Restart the S-UI service. The new protocol immediately appears in API responses and the web interface dropdowns without additional frontend changes.

## Handling Custom Configuration Fields

S-UI stores outbound configurations as generic JSON. When creating outbounds via the API at `/api/v2/outbounds`, include custom fields in the request body:

```bash
curl -X POST http://localhost:2095/app/api/v2/inbounds \
  -H "Content-Type: application/json" \
  -d '{
        "tag": "my-inbound",
        "type": "myproto",
        "listen": "0.0.0.0",
        "listen_port": 12345,
        "settings": { "encryption": "aes-256-gcm" }
      }'

```

The backend persists these fields without requiring database schema migrations. You only need schema modifications if you intend to query specific protocol fields directly via SQL.

## Optional: Customizing Subscription Links

If your protocol uses a custom URL scheme (like `vmess://`), extend the subscription generator in [`sub/linkService.go`](https://github.com/alireza0/s-ui/blob/main/sub/linkService.go). Modify the `addClientInfo` function to format your protocol's specific link syntax. Additionally, review [`util/genLink.go`](https://github.com/alireza0/s-ui/blob/main/util/genLink.go) if you need to customize how subscription URLs are constructed and exported to clients.

## Summary

- S-UI relies on **Sing-Box** interfaces; protocols must implement `Inbound` and/or `Outbound` adapters.
- Register new protocols in **[`core/register.go`](https://github.com/alireza0/s-ui/blob/main/core/register.go)** by importing your package and calling `RegisterInbound()` and `RegisterOutbound()` inside the respective registry functions.
- No frontend modifications are necessary—the UI dynamically reflects registered protocols from the backend.
- Custom fields persist automatically as JSON; no database schema changes are required.
- Rebuild the binary with [`./build.sh`](https://github.com/alireza0/s-ui/blob/main/./build.sh) to activate the protocol.

## Frequently Asked Questions

### Do I need to modify the S-UI frontend to add a new protocol?

No. The web interface dynamically queries the backend for available protocol types. Once registered in [`core/register.go`](https://github.com/alireza0/s-ui/blob/main/core/register.go) and rebuilt, your protocol automatically populates the inbound and outbound dropdown menus in the settings panel.

### What Sing-Box interfaces must my protocol implement?

Your package must satisfy the **`Inbound`** interface for accepting connections and the **`Outbound`** interface for routing traffic. These require implementing methods for adapter initialization, service startup, and graceful shutdown. Reference existing protocol implementations in the Sing-Box repository for exact method signatures.

### Where are built-in protocols registered in S-UI?

Built-in protocols like VMess, Shadowsocks, and Trojan follow the same registration pattern in **[`core/register.go`](https://github.com/alireza0/s-ui/blob/main/core/register.go)**. Examine the imports and registration calls in `InboundRegistry()` and `OutboundRegistry()` to see how native Sing-Box protocols hook into the system.

### Can I use existing Sing-Box plugins instead of writing a new protocol?

Yes. If your desired protocol already exists as a Sing-Box plugin, simply import that package in [`core/register.go`](https://github.com/alireza0/s-ui/blob/main/core/register.go) and call its `RegisterInbound` or `RegisterOutbound` functions. This approach requires no custom protocol code—only the registry import and rebuild steps.