axevpn_flutter 2.0.0 copy "axevpn_flutter: ^2.0.0" to clipboard
axevpn_flutter: ^2.0.0 copied to clipboard

Dual-protocol VPN plugin for Flutter supporting OpenVPN and WireGuard on Android (16 KB page-size ready) and iOS.

axevpn_flutter #

pub package pub points popularity License: GPL v3 Platform

A Flutter plugin that provides OpenVPN and WireGuard VPN connectivity for Android and iOS.
Built with Android 15+ 16 KB page-size compatibility and modern Flutter 3.10+ / Dart 3.0+ support.


Table of Contents #


Features #

Feature OpenVPN WireGuard
Android support
iOS support
Real-time status monitoring
Connection stats (bytes in/out)
Auto-reconnect handling
Split tunneling (package bypass)
TCP & UDP protocol
Android 15+ 16 KB page-size
Modern cryptography

Platform Support #

Platform Minimum Version
Android 7.0 (API 24)
iOS 16.0

Installation #

Add to your pubspec.yaml:

dependencies:
  axevpn_flutter: ^2.0.0

Then run:

flutter pub get

Quick Start #

OpenVPN #

import 'package:axevpn_flutter/openvpn_flutter.dart';

// 1. Instantiate
final vpn = OpenVPN(
  onVpnStatusChanged: (VpnStatus? status) {
    print('Duration: ${status?.duration}');
    print('Bytes in: ${status?.byteIn}  Bytes out: ${status?.byteOut}');
  },
  onVpnStageChanged: (VPNStage stage, String rawStage) {
    print('Stage: $stage');
  },
);

// 2. Initialize (required before connect)
await vpn.initialize(
  // iOS only ↓
  groupIdentifier: 'group.com.example.vpn',
  providerBundleIdentifier: 'com.example.app.VPNExtension',
  localizedDescription: 'My VPN',
);

// 3. Connect
final ovpnConfig = '''
client
dev tun
proto udp
remote vpn.example.com 1194
...
''';

await vpn.connect(ovpnConfig, 'My Server');

// 4. Disconnect
vpn.disconnect();

WireGuard #

import 'package:axevpn_flutter/wireguard_flutter.dart';

// 1. Instantiate
final wg = WireGuard(
  onVpnStatusChanged: (WireGuardStatus? status) {
    print('Duration: ${status?.duration}');
    print('Bytes in: ${status?.byteIn}  Bytes out: ${status?.byteOut}');
  },
  onVpnStageChanged: (WGStage stage, String rawStage) {
    print('Stage: $stage');
  },
);

// 2. Initialize
await wg.initialize(
  // iOS only ↓
  groupIdentifier: 'group.com.example.vpn',
  providerBundleIdentifier: 'com.example.app.WGExtension',
  localizedDescription: 'My VPN',
);

// 3. Connect — pass raw WireGuard .conf content
final wgConfig = '''
[Interface]
PrivateKey = <your_private_key>
Address = 10.0.0.2/24
DNS = 1.1.1.1

[Peer]
PublicKey = <server_public_key>
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0
''';

await wg.connect(wgConfig, 'My WireGuard');

// 4. Disconnect
await wg.disconnect();

Android Setup #

1. Handle VPN permission result in MainActivity #

Kotlin (MainActivity.kt):

import com.axevpn.flutter.openvpn.AxeVPNFlutterPlugin

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    AxeVPNFlutterPlugin.connectWhileGranted(requestCode == 24 && resultCode == RESULT_OK)
    super.onActivityResult(requestCode, resultCode, data)
}

Java (MainActivity.java):

import com.axevpn.flutter.openvpn.AxeVPNFlutterPlugin;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    AxeVPNFlutterPlugin.connectWhileGranted(requestCode == 24 && resultCode == RESULT_OK);
    super.onActivityResult(requestCode, resultCode, data);
}

2. app/build.gradle (Kotlin DSL) #

android {
    compileSdk = 36
    ndkVersion = "27.0.12077973"   // Required for 16 KB page-size support

    defaultConfig {
        minSdk = 24
        targetSdk = 36
    }

    // Enable Android 15+ 16 KB memory page size
    experimentalProperties["android.experimental.enable16KPageSize"] = true

    packaging {
        jniLibs {
            useLegacyPackaging = true
        }
    }
}

3. android/gradle.properties #

android.experimental.enable16KPageSize=true
android.bundle.enableUncompressedNativeLibs=false

4. AndroidManifest.xml #

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
    android:extractNativeLibs="true"
    ...>

iOS Setup #

1. Enable capabilities in Xcode #

In your Runner target (and Network Extension target), enable:

  • App Groups – create group.com.yourapp.vpn
  • Network Extensions – enable Packet Tunnel

2. Add Network Extension target #

In Xcode → File → New → Target → Network Extension.
Name it (e.g., VPNExtension) and set the same App Group.

OpenVPN Extension

Add to ios/Podfile under the new target:

target 'VPNExtension' do
  use_frameworks!
  pod 'OpenVPNAdapter', :git => 'https://github.com/ss-abramchuk/OpenVPNAdapter.git', :tag => '0.8.0'
end

Copy PacketTunnelProvider.swift to VPNExtension/:

// See example/ios/VPNExtension/ in the repository

WireGuard Extension

target 'WGExtension' do
  use_frameworks!
  pod 'WireGuardKit', :git => 'https://git.zx2c4.com/wireguard-apple', :tag => '1.0.15-26'
end

3. Info.plist — Network Extension target #

<key>NSExtension</key>
<dict>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.networkextension.packet-tunnel</string>
    <key>NSExtensionPrincipalClass</key>
    <string>$(PRODUCT_MODULE_NAME).PacketTunnelProvider</string>
</dict>

API Reference #

OpenVPN API #

OpenVPN constructor

OpenVPN({
  Function(VpnStatus? data)? onVpnStatusChanged,
  Function(VPNStage stage, String rawStage)? onVpnStageChanged,
})
Parameter Type Description
onVpnStatusChanged Function(VpnStatus?) Called when bytes/duration update
onVpnStageChanged Function(VPNStage, String) Called on every stage transition

initialize()

Future<void> initialize({
  String? groupIdentifier,          // iOS: App Group ID
  String? providerBundleIdentifier, // iOS: Extension bundle ID
  String? localizedDescription,     // iOS: Description in Settings
  Function(VpnStatus)? lastStatus,  // Callback with last known status
  Function(VPNStage)? lastStage,    // Callback with last known stage
})

connect()

Future connect(
  String config,    // Raw .ovpn file content
  String name,      // Display name for notification
  {
    String? username,
    String? password,
    List<String>? bypassPackages, // Android: packages to exclude from VPN
    bool certIsRequired = false,
  }
)

disconnect()

void disconnect()

Other methods

Future<VPNStage> stage()
Future<VpnStatus> status()
Future<bool> isConnected()
Future<bool> requestPermissionAndroid()
static Future<String?> filteredConfig(String? config)

VpnStatus

class VpnStatus {
  final DateTime? connectedOn; // Time VPN connected
  final String? duration;      // e.g. "00:05:32"
  final String? byteIn;        // Bytes received (as string)
  final String? byteOut;       // Bytes sent (as string)
  final String? packetsIn;
  final String? packetsOut;
}

WireGuard API #

WireGuard constructor

WireGuard({
  Function(WireGuardStatus? data)? onVpnStatusChanged,
  Function(WGStage stage, String rawStage)? onVpnStageChanged,
})

initialize()

Future<void> initialize({
  String? groupIdentifier,
  String? providerBundleIdentifier,
  String? localizedDescription,
  Function(WireGuardStatus)? lastStatus,
  Function(WGStage)? lastStage,
})

connect()

Future connect(
  String config,      // Raw WireGuard .conf content
  String tunnelName,  // Display name
)

Other methods

Future<void> disconnect()
Future<WGStage> stage()
Future<WireGuardStatus> status()

WireGuardStatus

class WireGuardStatus {
  final Duration? duration;         // Connection duration
  final String? lastPacketReceive;  // Last handshake timestamp
  final String? byteIn;             // Bytes received
  final String? byteOut;            // Bytes sent
}

VPN Stages #

OpenVPN (VPNStage)

Stage Description
prepare Preparing to connect
authenticating Verifying credentials
connecting Establishing tunnel
connected Tunnel is up
disconnecting Tearing down tunnel
disconnected Tunnel is down
denied VPN permission denied
error Connection error
wait_connection Waiting for network
get_config Fetching configuration
tcp_connect TCP handshake
udp_connect UDP handshake
assign_ip IP assignment
resolve DNS resolution
exiting Process exiting

WireGuard (WGStage)

Stage Description
preparing Preparing to connect
connecting Establishing tunnel
connected Tunnel is up
disconnecting Tearing down tunnel
disconnected Tunnel is down
denied VPN permission denied
error Error occurred

Advanced Usage #

Split Tunneling (OpenVPN only) #

Exclude specific apps from the VPN tunnel on Android:

await vpn.connect(
  ovpnConfig,
  'My Server',
  bypassPackages: [
    'com.google.android.youtube',
    'com.whatsapp',
  ],
);

Filter Duplicate Remotes #

If your .ovpn has many remote entries and causes ANR on some devices:

String? singleRemoteConfig = await OpenVPN.filteredConfig(rawConfig);

Request Android Permission Manually #

bool granted = await vpn.requestPermissionAndroid();
if (granted) {
  await vpn.connect(config, 'Server');
}

Toggle Connection #

if (await vpn.isConnected()) {
  vpn.disconnect();
} else {
  await vpn.connect(config, 'Server');
}

Troubleshooting #

Android #

Problem Solution
Build fails with 16 KB error Install NDK 27.0.12077973; set enable16KPageSize=true
VPN permission dialog not shown Call requestPermissionAndroid() before connect()
OpenVPN need to be initialized Call initialize() before connect()
ANR on connect Use OpenVPN.filteredConfig() to reduce remote entries

iOS #

Problem Solution
groupIdentifier is required Pass all three iOS params to initialize()
Network Extension not found Verify bundle IDs match providerBundleIdentifier in Xcode
Status not updating after disconnect Register onVpnStageChanged before calling initialize()

Changelog #

See CHANGELOG.md for a complete version history.


License #

Licensed under the GNU General Public License v3.0 – see LICENSE for details.

OpenVPN® is a registered trademark of OpenVPN Inc.
WireGuard® is a registered trademark of Jason A. Donenfeld.


Forked from openvpn_flutter and extended with WireGuard support and Android 15+ 16 KB page-size compatibility.

0
likes
130
points
0
downloads

Publisher

verified publisherlinkze.me

Weekly Downloads

Dual-protocol VPN plugin for Flutter supporting OpenVPN and WireGuard on Android (16 KB page-size ready) and iOS.

Repository (GitHub)
View/report issues
Contributing

Topics

#vpn #openvpn #wireguard #networking #security

Documentation

Documentation
API reference

License

GPL-3.0 (license)

Dependencies

flutter

More

Packages that depend on axevpn_flutter

Packages that implement axevpn_flutter