A lightweight Windows GUI client for sing-box, built with Tauri 2, React, and TypeScript.
- Latest version:
v1.4.4 - Downloads: https://github.com/lieshy521-9577/WSingBox/releases/tag/v1.4.4
- Windows x64 assets: NSIS installer, portable ZIP, and
SHA256SUMS.txt
The main workspace is optimized for a small desktop window:
- top bar for runtime status, current route, and quick start/stop
Nodespage for outbound group selection, node latency testing, and node editing- left sidebar for profile import and switching between saved local/URL profiles
- Import sing-box JSON profiles with compatibility cleanup for sing-box
1.12.x - Import from either local JSON or subscription URL through a unified import modal
- Validate profiles before import: node/group count, TUN detection, compatibility warnings
- Auto-extract proxy nodes and outbound groups from imported configs
- Select groups or nodes from both the
Nodespage and theOverviewpage - Refresh saved URL-based profiles without re-pasting the subscription link
- Start sing-box with elevation only when the active config contains
tuninbound - Run a startup health check before launch: core path, runtime config, mixed port, TUN requirement
- Auto-inject a local
mixedinbound fallback when needed - Manage Windows system proxy state and restore the previous proxy state on stop/exit
- Keep the UI responsive while the sing-box core is starting
- Start without unavailable remote rule sets instead of failing the whole runtime
- Test node latency from the client
- Edit single nodes, route rules, DNS settings, TUN settings, and rule sets
- View runtime logs inside the client
- Light/dark desktop UI with custom titlebar and tray integration
SingBox/
|-- src/ # React frontend
| |-- components/ # UI components
| |-- hooks/ # App state and actions
| `-- types/ # TypeScript interfaces
|-- src-tauri/ # Rust backend
| `-- src/
| `-- commands/ # IPC commands (config, singbox, proxy, latency)
|-- bin/ # sing-box.exe
`-- package.json
- Frontend: React 18, TypeScript, Tailwind CSS, Lucide Icons
- Backend: Rust, Tauri 2
- Proxy Core: sing-box
- Build: Vite, Cargo
- Node.js
>= 18 - Rust stable toolchain
- Windows 10/11 with WebView2 runtime
sing-box.exeavailable inbin/or otherwise discoverable by the app
npm install
npm run tauri dev
npm run tauri buildIf you do not want to ship an installer, you can ship a portable zip plus a PowerShell install script.
- Build the desktop app:
npm run tauri build- Package the portable bundle:
npm run package:portable- Distribute the generated zip:
src-tauri/target/release/bundle/portable/SingBox-Client_1.4.4_x64-portable.zip
- On the target machine, unzip it and run:
powershell -ExecutionPolicy Bypass -File .\install.ps1This installs the app into %LOCALAPPDATA%\Programs\SingBox Client, copies the bundled bin/ runtime files, creates shortcuts, and launches the client. A separate sing-box installation is not required.
- Launch the application.
- Click
Import Profile. - Choose either
Local JSONorSubscription URL. - Review the import preflight result before confirming the import.
- Nodes and groups are extracted and shown in the UI.
- Click
Startto launch sing-box. - The client runs a startup health check before starting the core.
- If the active config contains a
tuninbound, Windows will show aUACprompt. - Click
Stopto terminate sing-box and restore the previous Windows proxy state.
- Imported profiles are stored locally in the client profile store
Localprofiles come from JSON files you picked in ExplorerURLprofiles come from subscription links and can be refreshed in-place from the sidebar- Only
http://andhttps://sources are treated as URL profiles; Windows file paths are always treated as local files - Editing a saved profile updates the stored JSON and, if active, immediately refreshes the runtime config
- Importing a new profile does not clear existing saved profiles
The imported file must be a valid sing-box JSON config. The client works best when the file follows the usual sing-box structure:
outboundsshould exist and include real proxy outbounds such asvless,vmess,trojan,shadowsocks,hysteria2,tuic, orwireguard- outbound groups should use
type: "selector"ortype: "urltest" - each group member listed in
outbounds[].outboundsshould match an existing outboundtag - if you want stable selection behavior, every node and group should have a unique
tag inboundsis optional because the client can inject a fallbackmixedinbounddnsandrouteare optional, but if present they must already be valid sing-box sections
{
"inbounds": [
{
"type": "mixed",
"tag": "mixed-in",
"listen": "127.0.0.1",
"listen_port": 7890
}
],
"outbounds": [
{
"type": "vless",
"tag": "node-a",
"server": "example.com",
"server_port": 443,
"uuid": "00000000-0000-0000-0000-000000000000",
"tls": {
"enabled": true,
"server_name": "example.com"
}
},
{
"type": "selector",
"tag": "proxy",
"outbounds": ["node-a"],
"default": "node-a"
},
{
"type": "direct",
"tag": "direct"
},
{
"type": "block",
"tag": "block"
}
],
"route": {
"final": "proxy"
}
}- If the profile contains
tuninbound, startup will require elevation. - If no
mixedinbound exists, the client will add one for local proxy mode. - The import modal performs a lightweight preflight check before saving the profile.
- URL profiles can be refreshed later from
Saved Profiles. - Imported profiles are saved into the client profile store. Importing a new file does not clear existing saved profiles.
- Group selection works best when selector and urltest groups already have correct
defaultandoutboundsrelationships.
- Whether the content can be parsed as sing-box JSON or base64-encoded sing-box JSON
- Whether proxy nodes can be extracted
- Whether selector/urltest groups can be extracted
- Whether a TUN inbound is present
- Whether the profile is likely to need extra attention before startup
- The JSON parses successfully.
- Each real proxy outbound has required protocol-specific fields.
- Every selector or urltest member tag points to an existing outbound.
route.finalultimately points to a valid group or node.- If using Reality, TLS, TUIC, or Hysteria2, those protocol fields already match your sing-box version.
- VLESS
- VMess
- Shadowsocks
- Trojan
- Hysteria2
- TUIC
- WireGuard
The client automatically normalizes some older config details for sing-box 1.12.x:
- Moves per-server
strategyinto the DNS top-level when needed - Removes deprecated DNS servers with
type: "block" - Migrates legacy
sslblocks totlswhentlsis missing - Merges legacy TUN
inet4_*andinet6_*address fields into the current array-based fields - Removes
sniff_override_destinationfrom route rule sniff actions when required - Adds a local
mixedinbound on port7890if not present
The client also injects the required ENABLE_DEPRECATED_* compatibility environment variables only into the spawned sing-box process. Users do not need to configure system-wide environment variables manually.
Remote rule sets are treated as optional startup enhancements, not as a reason to block the whole proxy runtime:
- Cached remote rule sets are converted to local
binaryrule sets before launching sing-box. - Missing remote rule sets are removed from the launch config together with DNS/route rules that reference them.
- The core starts without unavailable rule sets so basic proxy connectivity can still work.
- Rule-set downloads run in the background and are used on the next startup after they succeed.
Check for Updatesin theAboutpage is informational only; no updater backend is wired yet- Runtime logs depend on what sing-box writes to stdout/stderr
- Startup health check is intentionally lightweight; it catches common local issues, not every protocol-level failure
- Background rule-set download status is not yet surfaced in the UI
Check the startup health badges in the header. The client now pre-checks:
- bundled
sing-box.exeavailability - runtime config presence
- mixed inbound port availability
- whether the active profile requires TUN/UAC elevation
Use the refresh action in Saved Profiles. Only URL-based profiles expose refresh because the original source can be fetched again.
Import validation only checks structure and common compatibility problems. It does not guarantee the remote server, credentials, Reality keys, TLS fields, or protocol-specific values are correct.
If a profile depends on remote rule sets and they are not cached yet, the client can start without those rule sets. Keep the app online for the background download to complete, then reconnect to use the cached local rule-set files.
The desktop UI is intentionally optimized for a small default window:
- one primary import action instead of separate stacked file/URL panels
- compact health/status chips instead of large diagnostic cards
- source-aware saved profiles with direct refresh/edit/delete actions
- small-screen-safe sidebar behavior so saved profiles remain reachable in short window heights
MIT
