This guide explains how to integrate sing-box with the VPN Client Engine Flutter plugin.
This is the most reliable approach for mobile platforms.
# Install Go (if not already installed)
# Download from https://golang.org/dl/
# Install gomobile
go install golang.org/x/mobile/cmd/gomobile@latest
go install golang.org/x/mobile/cmd/gobind@latest
# Initialize gomobile
gomobile init- Create Go wrapper for sing-box:
// singbox_wrapper.go
package main
import (
"C"
"encoding/json"
"fmt"
"log"
"os"
"path/filepath"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/experimental/libbox"
)
//export StartSingBox
func StartSingBox(configPath *C.char) *C.char {
configPathStr := C.GoString(configPath)
// Read configuration file
configBytes, err := os.ReadFile(configPathStr)
if err != nil {
return C.CString(fmt.Sprintf("error: %v", err))
}
// Parse configuration
var config option.Options
err = json.Unmarshal(configBytes, &config)
if err != nil {
return C.CString(fmt.Sprintf("error parsing config: %v", err))
}
// Create and start sing-box
box, err := libbox.NewBox(config, nil, nil, nil, nil)
if err != nil {
return C.CString(fmt.Sprintf("error creating box: %v", err))
}
err = box.Start()
if err != nil {
return C.CString(fmt.Sprintf("error starting box: %v", err))
}
return C.CString("success")
}
//export StopSingBox
func StopSingBox() *C.char {
// Implementation to stop sing-box
return C.CString("stopped")
}
func main() {}- Build for Android:
gomobile bind -target=android -o=singbox.aar ./singbox_wrapper.go- Build for iOS:
gomobile bind -target=ios -o=singbox.framework ./singbox_wrapper.goThe iOS implementation already uses Network Extension with sing-box.
- Xcode with Network Extension capability
- sing-box Network Extension target
- Proper entitlements
// In VpnclientEngineFlutterPlugin.swift
private func startSingBox(config: String, result: @escaping FlutterResult) {
NETunnelProviderManager.loadAllFromPreferences { managers, error in
// ... implementation
}
}The Windows implementation launches sing-box as a separate process.
// In vpnclient_engine_flutter_plugin.cpp
bool VpnclientEngineFlutterPlugin::startSingBox(std::string configPath) {
std::string command = "sing-box run -c \"" + configPath + "\"";
// ... implementation
}- Add VPN permissions to AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />- Add sing-box AAR to build.gradle:
dependencies {
implementation files('libs/singbox.aar')
}- Update Android plugin:
// In VpnclientEngineFlutterPlugin.kt
private fun startSingBoxWithConfig(config: String, result: Result) {
try {
// Save config to file
val configFile = File(context.cacheDir, "sing-box-config.json")
FileOutputStream(configFile).use { fos ->
fos.write(config.toByteArray())
}
// Call Go mobile bindings
val result = Singbox.startSingBox(configFile.absolutePath)
if (result.startsWith("success")) {
isVpnRunning = true
sendConnectionStatus("connected")
result.success("Connected to VPN using sing-box")
} else {
result.error("SINGBOX_ERROR", result, null)
}
} catch (e: Exception) {
result.error("SINGBOX_ERROR", "Failed to start sing-box", e.message)
}
}- Enable Network Extension capability in Xcode
- Add sing-box framework to project
- Create Network Extension target
- Install sing-box executable
- Add to PATH or specify full path
- Run with administrator privileges
// In lib/vpnclient_engine_flutter.dart
abstract class VpnclientEngineFlutterPlatform {
Future<void> connect({required String url, String? config});
Future<void> disconnect();
Future<String?> getPlatformVersion();
Future<bool> requestPermissions();
Future<String> getConnectionStatus();
}// In lib/platforms/android.dart
class AndroidVpnclientEngineFlutter extends VpnclientEngineFlutterPlatform {
@override
Future<void> connect({required String url, String? config}) async {
// Call native Android implementation
}
@override
Future<bool> requestPermissions() async {
// Request VPN permissions
}
}{
"log": {
"level": "info"
},
"inbounds": [
{
"type": "tun",
"tag": "tun-in",
"interface_name": "tun0",
"inet4_address": "172.19.0.1/30",
"auto_route": true,
"strict_route": true,
"sniff": true
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct"
}
]
}// Test sing-box integration
await VPNclientEngine.connect(
url: "sing-box://config",
config: singBoxConfig
);- Implement Go mobile bindings
- Add proper error handling
- Implement VPN interface setup
- Add configuration validation
- Create comprehensive tests
- Add documentation