features
The details behind each of these are in the README, which also lists what is not supported yet.
configuration
sbr takes a sing-box JSON config as it is, with sing-box's flags: sbr run -c config.json, sbr check, and the rule-set compile, decompile, match and format subcommands. Routing follows sing-box's rule semantics, and binary rule-sets (.srs v1–5) are read and written in sing-box's format.
The parser is as strict as sing-box's: an unknown field is an error reported with its JSON path. A field sing-box accepts and sbr has not implemented is also an error, unless it cannot change where traffic goes, in which case it is a warning. The app runs every profile through this parser when it is imported.
protocols
- vless
With the Vision flow and REALITY. REALITY sends X25519MLKEM768, which XTLS REALITY servers have required since 2026-09-08.
- hysteria2
Salamander, port hopping and Brutal. When the phone moves between Wi-Fi and cellular, live connections migrate to the new path, so a download or call continues across the handover.
- trojan
Over TLS or any of the transports below.
- vmess
AEAD.
- shadowsocks
AEAD and 2022 ciphers, TCP and UDP, UDP over TCP v1 and v2.
- tuic
Version 5, every UDP relay mode, 0-RTT.
- wireguard
A userspace endpoint used as an outbound.
- anytls
With its padding scheme.
- shadowtls
Versions 1, 2 and 3.
- xhttp
An sbr extension for VLESS, trojan and VMess, taking Xray's field names: stream-one, stream-up and packet-up over HTTP/1.1, HTTP/2 or HTTP/3, the transport Xray uses behind CDNs.
Also socks, http, direct, selector, urltest and detour chains, and the ws, httpupgrade, grpc and http transports. Each is tested against real sing-box servers, and REALITY, Vision, XHTTP and hysteria2 also against Xray-core and apernet hysteria.
browser tls fingerprints
Every TLS client over TCP (trojan, VLESS, VMess, the transports, ShadowTLS's camouflage handshake, AnyTLS and DNS over HTTPS) sends a browser's ClientHello by default, and utls.fingerprint picks which:
| fingerprint | source | ja4 |
|---|---|---|
| chrome | Chrome 155, captured from the browser | t13d1517h2_8daaf6152771_cb7bf5808d99 |
| safari, ios | captured from macOS 27 URLSession | t13d2013h2_a09f3c656075_7f0f34a4126d |
| firefox | Firefox 148 | t13d1715h2_5b57614c22b0_a54fffd0eb61 |
sing-box 1.14.4 and Xray 26.10 still send Chrome 133's ClientHello for chrome, which current Chrome no longer matches. Fingerprints sbr does not have are refused rather than mapped to another browser.
failover that sees blocking after the handshake
Censors now let a connection start and then stop it: Russia's TSPU freezes a flow after about 16–20 KB, and the GFW has reset all of TCP/443 for over an hour. A handshake still succeeds, so sing-box's urltest keeps choosing the dead server. sbr adds two checks to every urltest member without new config fields: a 64 KiB data probe after each latency probe, and passive detection of resets, unanswered requests and stalls in live traffic. A failing member is skipped for 120 s, doubling to 30 minutes on each relapse; stalled connections on it are closed so apps retry on the new path at once.
Probes to members that share a server are spaced 200–1200 ms apart and their period varies by up to 20%, so a profile with six identities on one server does not open six handshakes in the same millisecond on a fixed clock.
automatic clienthello fragmentation
When a TLS or REALITY handshake is reset before the server sends a byte, which is what SNI filtering looks like from the client, sbr retries it at once with the ClientHello split across TLS records, and then across TCP segments as well. The server name is cut inside every label, so no record or segment holds a whole label of it. The setting lasts until the network changes. fragment and record_fragment set it by hand, as in sing-box.
For QUIC, hysteria2 without Salamander and TUIC put the two halves of the server name in different Initial packets, as quic-go does.
dns failover
When a DNS server errors, times out or answers SERVFAIL or REFUSED, the query goes to the profile's next network resolver, after at most 4 s. The failed server is skipped for later queries and probed in the background, about once a minute, until it answers. sing-box does not fail over, so a profile whose first resolver is unreachable through the current path resolves nothing.
userspace tcp stack
sbr has its own TCP stack for the TUN, which the app uses on iOS and tvOS. Each segment crosses the kernel once instead of twice, which at MTU 1280 gave 1.5–1.75× the throughput of the kernel stack at about 40% less CPU per byte (benchmarks). An app's connect completes only once the outbound has connected, so a failed connect or a reject rule makes it fall back immediately. Buffers grow with use, idle connections hold none, and on iOS they are capped at 128 KiB per direction per connection and 8 MiB in total, inside the extension's memory limit. IPv4 and IPv6 fragments are reassembled, so a VPN nested inside the tunnel keeps working.
the app
- profiles
Added from a
sing-box://import-remote-profilelink, an https URL or a JSON file. Remote profiles refresh when the app opens and from the tunnel itself, without the app. - groups
Every selector in the profile, what each nested group resolves to and its measured latency, with a test button.
- live connections
Each open connection with its destination, sniffed domain, rule, route and current rate, sorted by when bytes last moved. Swipe to close one.
- per-site rules
Long-press a connection to always route its domain through a chosen server or group. The rule survives profile switches and refreshes, and connections to that domain reconnect on the new route.
- auto-connect
Connects on every network except the Wi-Fi networks you trust.
- shortcuts
Connect, disconnect, toggle and select-outbound intents, and a Control Center toggle.
- diagnose
Checks DNS, TCP, HTTP/3 and a bulk download through the tunnel, and reports why the tunnel last stopped if it was not asked to.
On the command line, experimental.clash_api serves the endpoints yacd, metacubexd and zashboard use.