flutter_v2ray_plus
Flutter plugin to run VLESS/VMESS as a local proxy and VPN on Android and iOS. V2Ray/Xray core. Shadowsocks, Trojan, Socks 5 support.
⚡️ Provides fine-grained routing for domains, sites, and apps, with built-in status tracking, delay testing, and extended configuration options.
Third-Party Components
This package uses the following third-party components:
- XRay.xcframework - Xray core binary for iOS
- jniLibs - Xray core binaries for Android
In contrast to similar plugins, we provide both iOS and Android versions out of the box and for free, with the package being fully open-source.
Make sure to give a like on pub.dev and star on GitHub if this package was useful for you <3
Table of contents
- Key Features
- Quick Start (TL;DR)
- Requirements
- Installation
- Platform setup (step-by-step)
- Usage examples
- Contributing / Contact / License
Key features
- Supports iOS and Android out of the box, with routing and similar features available
- Supports Android 16KB page size (API 35+)
- Run flutter_v2ray_plus as a local proxy or using the VPN mode (Network Extension / VpnService).
- Parse VLESS/VMESS share links and generate ready-to-run configurations.
- Measure server delay (ping) for a configuration.
- Edit configuration (ports, DNS, routing, etc.).
Quick Start (TL;DR)
- Install the package (see Installation).
- Complete platform setup (iOS / Android).
- Initialize the plugin and start flutter_v2ray_plus from your app.
Minimal copy‑paste example:
import 'package:flutter/material.dart';
import 'package:flutter_v2ray_plus/flutter_v2ray_plus.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late final FlutterV2ray _flutterV2Ray;
@override
void initState() {
super.initState();
_flutterV2Ray = FlutterV2ray();
_init();
}
Future<void> _init() async {
await _flutterV2Ray.initializeVless(
providerBundleIdentifier: 'com.example.myapp.VPNProvider',
groupIdentifier: 'group.com.example.myapp',
);
}
Future<void> _startFromShareLink(String shareLink) async {
final FlutterV2RayURL parser = FlutterV2ray.parseFromURL(shareLink);
final String config = parser.getFullConfiguration();
final int delayMs = await _flutterV2Ray.getServerDelay(config: config);
print('Server delay: ${delayMs}ms');
final bool allowed = await _flutterV2Ray.requestPermission();
if (!allowed) return;
await _flutterV2Ray.startVless(
remark: parser.remark,
config: config,
);
}
Future<void> _stop() async {
await _flutterVless.stopVless();
}
@override
Widget build(BuildContext context) => Container();
}
Requirements
- Flutter SDK (the minimum supported version used by the package).
- Android: recommended
minSdkVersion>= 23; settargetSdkVersionto a recent API. - iOS:
iOS Deployment Target>= 15.0 (may vary depending on Network Extension usage). - Running VPN mode on iOS requires Network Extension and a provisioning profile that allows it.
Installation
From pub.dev
dependencies:
flutter_v2ray_plus: replace_with_current_plugin_version
Local development
dependencies:
flutter_v2ray_plus:
path: ../flutter_v2ray_plus
Then run:
flutter pub get
Platform setup (step-by-step)
Follow the platform steps below — without these the plugin cannot run VPN/Network Extension.
iOS
The XRay.xcframework (required for iOS) is automatically downloaded during pod install — no manual download needed.
Android
- Add the attribute android:extractNativeLibs="true" to the
<application
android:name=".MyApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:extractNativeLibs="true">
. . .
</application>
- Set minSdkVersion to >= 23. Ensure your
minSdkVersionandtargetSdkVersionmatch plugin and Play Store requirements.
Google Play note: apps that modify network traffic may require a privacy policy and additional disclosure in the store listing.
Usage examples
URL parser
import 'package:flutter_v2ray_plus/flutter_v2ray_plus.dart';
final String link = 'vmess://...'; // or vless://, trojan:// etc.
FlutterV2RayURL parsed = FlutterV2ray.parseFromURL(link);
print('Remark: ${parsed.remark}');
final String config = parsed.getFullConfiguration();
print('Config JSON: $config');
Edit Configuration
An example of how we work with routing through configuration is available in our example.
// Change listening port
parsed.inbound['port'] = 10890;
// Change listening host
parsed.inbound['listen'] = '0.0.0.0';
// Change dns
parsed.dns = {
"servers": ["1.1.1.1"]
};
// and ...
Start / Stop FlutterV2Ray
final flutterV2Ray = FlutterV2ray();
await flutterV2Ray.initializeVless(
providerBundleIdentifier: 'com.wisecodex.vpnapp',
groupIdentifier: 'group.com.wisecodex.vpnapp',
);
if (await flutterV2Ray.requestPermission()) {
await flutterV2Ray.startVless(
remark: 'My server',
config: newConfig,
blockedApps: null, // list of package names
bypassSubnets: FlutterV2ray.defaultBypassSubnets(),
proxyOnly: false,
);
}
await flutterV2Ray.stopVless();
FAQ / common issues
Q: The VPN permission is granted but the VPN doesn’t start. A: Check that providerBundleIdentifier and groupIdentifier match the values in Xcode, and that the provisioning profile allows Network Extensions.
Q: My Play Store submission was rejected. A: Ensure your app includes a clear privacy policy and a disclosure about VPN/proxy usage in the store listing.
Q: **``** shows very high latency. A: Verify DNS, server address, and network reachability. Try from a different network or device to exclude local network issues.
Contributing / Contact / License
Contact
- By email - shafiqucbl@gmail.com
All rights reserved. Muhammad Shafique - https://shafique.dev