VPNclient Engine Flutter is a Flutter plugin that provides a high-level API for controlling VPN connections from a Dart/Flutter app. It wraps the native VPNclient Engine library, allowing Flutter developers to integrate advanced VPN functionality into their apps with ease. With this plugin, you can start and stop VPN connections, switch servers, apply routing rules, and listen to connection events using simple Dart calls, without worrying about platform-specific implementation details.
- Seamless Integration: The plugin is built to be cross-platform. It uses platform-specific binaries and code (written in C++ and integrated via Dart FFI) to interface with iOS, Android, Windows, macOS, and Linux, but exposes a unified Dart interface. This means you write your VPN logic once in Dart and it works everywhere Flutter does.
- Intuitive API: The API is designed with Flutter developers in mind. You can initialize the VPN engine, connect to a server, and listen for status changes using streams and futures. The plugin handles asynchronous calls and background threads internally.
- Powered by VPNclient Engine: Under the hood, this plugin utilizes the native VPNclient Engine, which supports multiple protocols (Xray/VMess/VLESS/Reality, WireGuard, OpenVPN, etc.) and drivers. The plugin abstracts the complexity, so you can, for example, simply call
connect()
and the engine will take care of setting up a tun interface or proxy as needed on that platform.
- ✅ iOS (15.0+)
- ✅ Android (5.0+)
- ✅ macOS (Intel/Silicon)
- ✅ Windows
- ✅ Unix (Linux/Debian/Ubuntu)
Each platform uses the native capabilities provided by VPNclient Engine:
- On Android and iOS, the engine uses the system VPN APIs (VpnService, NetworkExtension) to create a VPN tunnel.
- On desktop, it can either create a TUN interface or run as a local proxy (depending on driver configuration).
Internally, the plugin acts as a bridge between Dart and the native engine. It uses a combination of Dart FFI (Foreign Function Interface) and platform-specific setup to communicate with the native library. The basic flow:
flowchart LR
subgraph subGraph0["Flutter Application"]
UI@{ label: "Your Flutter App (<span style=\"color:\">Flutter UI)</span>" }
end
subgraph subGraph1["Flutter Plugin"]
Plugin["VPNclient Engine Flutter"]
end
subgraph subGraph2["Native Core"]
Core["VPNclient Engine Library"]
end
UI --> Plugin
Plugin --> Core
Core --> iOS["iOS"] & Android["Android"] & macOS["macOS"] & Windows["Windows"] & Linux["Linux"]
UI@{ shape: rect}
Diagram: Your Flutter app calls into the VPNclient Engine Flutter plugin (Dart layer). The plugin calls the native VPNclient Engine, which interfaces with the OS networking on each platform.
From a developer perspective, you primarily interact with the Dart API provided by this plugin. The plugin takes care of invoking native methods and ensures asynchronous operations (like connecting or disconnecting) do not block the UI thread.
Because this plugin sets up actual VPN tunnels, a few platform-specific configurations are required:
-
Android: No special code is needed (the plugin internally uses Android's
VpnService
), but you must declare the following in your app’s AndroidManifest.xml:<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
These ensure the app can open network connections and run a foreground service for the VPN. The plugin will handle launching the VPN service. (Note: You do not need to declare
BIND_VPN_SERVICE
in the manifest; the plugin uses the VpnService class which has that intent filter built-in.) -
iOS: Enable the Personal VPN capability for your app target in Xcode (this adds the necessary entitlements). Additionally, in your Info.plist, you might need to include a usage description for VPN if required. The VPNclient Engine uses a custom bundle identifier for its network extension (
click.vpnclient.engine
with anallow-vpn
key), but if you integrate via this plugin, typically enabling the capability is sufficient. When you run the app the first time, iOS will prompt the user to allow the VPN configuration. -
Windows: The app should be run with administrator privileges to create a TUN interface via WinTun. Alternatively, have the WinTun driver installed (which is usually present if WireGuard is installed on the system). No manifest changes are needed, but the user might need to approve driver installation if not already present.
-
macOS/Linux: The application will likely require root privileges or proper entitlements to create a tunnel (on macOS, Network Extension needs to be signed with the correct entitlements; on Linux, either run with root or configure
/dev/net/tun
access for the user). For development on macOS, you can enable "Network Extensions" in the sandbox if running unsigned.
Once the above are set up, you can use the plugin in your Dart code as shown below.
To start using VPN Client Engine Flutter, ensure you have Flutter installed and set up your project accordingly.
flutter pub add vpnclient_engine_flutter
// Initialize the Engine
VPNclientEngine.initialize();
// Clear subscriptions
VPNclientEngine.ClearSubscriptions();
// Add subscription
VPNclientEngine.addSubscription(subscriptionURL: "https://pastebin.com/raw/ZCYiJ98W");
//VPNclientEngine.addSubscriptions(subscriptionURLs: ["https://pastebin.com/raw/ZCYiJ98W"]);
// Update subscription
await VPNclientEngine.updateSubscription(subscriptionIndex: 0);
// Listen for connection status changes
VPNclientEngine.onConnectionStatusChanged.listen((status) {
print("Connection status: $status");
});
//Connect to server 1
await VPNclientEngine.connect(subscriptionIndex: 0, serverIndex: 1);
// Set routing rules
VPNclientEngine.setRoutingRules(
rules: [
RoutingRule(appName: "YouTube", action: "proxy"),
RoutingRule(appName: "google.com", action: "direct"),
RoutingRule(domain: "ads.com", action: "block"),
],
);
// Ping a server
VPNclientEngine.ping(subscriptionIndex: 0, index: 1);
VPNclientEngine.onPingResult.listen((result) {
print("Ping: sub=${result.subscriptionIndex}, server=${result.serverIndex}, latency=${result.latencyInMs} ms");
});
await Future.delayed(Duration(seconds: 10));
//Disconnect
await VPNclientEngine.disconnect();
Initializes the VPN Client Engine. This should be called before using any other method.
Connects to the specified VPN server.
index
: Index of the server fromgetServerList()
.s
Disconnects the active VPN connection.
Returns the current connection status (connected
, disconnected
, connecting
, error
).
Fetches the list of available VPN servers.
Pings a specific server to check latency.
index
: Index of the server fromgetServerList()
.- Returns: Latency in milliseconds.
Configures routing rules for apps or domains.
rules
: List of routing rules (e.g., route YouTube traffic through VPN, block ads.com).
Loads VPN subscriptions from the provided list of links.
subscriptionLinks
: A list of subscription file URLs.
Returns statistics for the current VPN session (e.g., data usage, session duration).
Enables or disables auto-connect functionality.
enable
:true
to enable,false
to disable.
Enables or disables the kill switch.
enable
:true
to enable,false
to disable.
Triggered when VPN connection status changes.
- Payload:
ConnectionStatus
(e.g.,connected
,disconnected
,error
).
Triggered when an error occurs.
- Payload:
ErrorCode
andErrorMessage
.
Triggered when the VPN server is switched.
- Payload:
newServerAddress
.
Triggered when a ping operation completes.
- Payload:
serverIndex
andlatencyInMs
.
Triggered when a subscription is loaded successfully.
- Payload:
subscriptionDetails
.
Triggered periodically with updated data usage statistics.
- Payload:
dataUsed
anddataRemaining
.
Triggered when routing rules are applied.
- Payload:
List<RoutingRule>
.
Triggered when the kill switch is activated.
Enum: connecting
, connected
, disconnected
, error
.
address
latency
location
isPreferred
appName
domain
action
(block
,allow
,routeThroughVPN
).
type
(socks5
,http
)address
port
credentials
Enum: invalidCredentials
, serverUnavailable
, subscriptionExpired
, unknownError
.
expiryDate
dataLimit
usedData
We welcome contributions! Please fork the repository and submit pull requests.
This project is licensed under the VPNclient Extended GNU General Public License v3 (GPL v3). See LICENSE.md for details.
For issues or questions, please open an issue on our GitHub repository.