Complete API documentation for React Native OpenVPN library
Everything you need to integrate secure VPN connections in your React Native app
| Section | Description | Link |
|---|---|---|
| ⚡ Core Methods | Essential VPN connection methods | View → |
| 🎧 Event Listeners | Real-time connection state monitoring | View → |
| 📋 Types & Interfaces | TypeScript definitions and configs | View → |
| 🏷️ Enums | Connection states and configuration options | View → |
| 🔄 Platform Differences | iOS vs Android specific behaviors | View → |
Essential methods for VPN connection management
| 🏷️ Platform | Android Only |
| 📝 Purpose | Request VPN permission from Android system |
| Must be called before connecting on Android |
Example Usage:
const isGranted = await OpenVPN.prepare();
if (!isGranted) {
console.log('❌ User denied VPN permission');
} else {
console.log('✅ VPN permission granted');
}| Return Value | Description |
|---|---|
true ✅ |
Permission granted by user |
false ❌ |
Permission denied by user |
- System VPN service unavailable
| 🏷️ Platform | Android Only |
| 📝 Purpose | Check if VPN permission is already granted |
| 💡 Use Case | Avoid showing permission dialog unnecessarily |
Example Usage:
const hasPermission = await OpenVPN.isPrepared();
if (hasPermission) {
console.log('✅ Ready to connect - permission already granted');
// Proceed with VPN connection
} else {
console.log('⏳ Permission required - call prepare() first');
}| Return Value | Description |
|---|---|
true ✅ |
Permission already granted |
false ⏳ |
Permission not yet granted |
| 🏷️ Platform | iOS & Android |
| 📝 Purpose | Initiate VPN connection with configuration |
| ⚡ Action | Establishes secure tunnel to VPN server |
Example Usage:
try {
const result = await OpenVPN.connect({
address: 'vpn.example.com',
username: 'user123',
password: 'password123',
openVPNConfig: configString,
iOSOptions: {
localizedDescription: 'My VPN Connection',
networkExtensionBundleIdentifier: 'com.myapp.vpn'
},
androidOptions: {
Notification: {
openActivityPackageName: 'com.myapp.MainActivity',
titleNotification: 'VPN Active'
}
}
});
console.log('🎉 Connected successfully:', result);
} catch (error) {
console.error('❌ Connection failed:', error);
}📥 Parameters:
params: ConnectionParams- Complete connection configuration
📤 Returns: Promise<string>
- Success message string
❌ Connection failed- Network or server issues❌ Invalid configuration- Malformed config parameters❌ Network unavailable- No internet connectivity❌ Authentication failed- Wrong credentials
| 🏷️ Platform | iOS & Android |
| 📝 Purpose | Terminate active VPN connection |
| ⚡ Action | Cleanly closes VPN tunnel |
Example Usage:
try {
await OpenVPN.disconnect();
console.log('✅ VPN disconnected successfully');
} catch (error) {
console.error('❌ Disconnect failed:', error);
}📤 Returns: Promise<string>
- Success message string
❌ Disconnect failed- System error during disconnection❌ No active connection- Already disconnected
| 🏷️ Platform | iOS & Android |
| 📝 Purpose | Get current VPN connection status |
| ⚡ Action | Returns immediate state value |
Example Usage:
const state = await OpenVPN.getCurrentState();
console.log('📊 Current VPN state:', state);
switch (state) {
case ConnectionState.CONNECTED:
console.log('🟢 VPN is active and connected');
break;
case ConnectionState.CONNECTING:
console.log('🟡 VPN connection in progress...');
break;
case ConnectionState.DISCONNECTED:
console.log('🔴 VPN is disconnected');
break;
}📤 Returns: Promise<ConnectionState>
| State | Icon | Description |
|---|---|---|
DISCONNECTED |
🔴 | Not connected to VPN |
CONNECTING |
🟡 | Connection attempt in progress |
CONNECTED |
🟢 | Successfully connected |
DISCONNECTING |
🟠 | Disconnection in progress |
ERROR |
❌ | Connection error occurred |
INVALID |
⚪ | Invalid/unknown state |
| 🏷️ Platform | iOS & Android |
| 📝 Purpose | Trigger state change event with current status |
| 💡 Use Case | Unified event-driven state management |
Example Usage:
// Request current state - will trigger state change listener
await OpenVPN.requestCurrentState();
// State will be delivered via addOpenVPNStateChangeListener callback
// No direct return value - uses event system for consistency📤 Returns: Promise<void>
- No direct return - triggers state change event instead
💡 Why use this?
- Maintains consistent event-driven architecture
- Ensures all state updates go through the same listener system
- Useful for refreshing UI state after app becomes active
Real-time monitoring of VPN connection state changes
| 🏷️ Platform | iOS & Android |
| 📝 Purpose | Monitor VPN state changes in real-time |
| ⚡ Action | Registers callback for state updates |
Example Usage:
// Register state change listener
const subscription = OpenVPN.addOpenVPNStateChangeListener((state) => {
console.log('🔄 VPN state changed to:', state.state);
switch (state.state) {
case OpenVPN.ConnectionState.CONNECTED:
console.log('🟢 VPN is now connected - secure tunnel active');
break;
case OpenVPN.ConnectionState.DISCONNECTED:
console.log('🔴 VPN is now disconnected - using regular connection');
break;
case OpenVPN.ConnectionState.CONNECTING:
console.log('🟡 VPN connecting - establishing secure tunnel...');
break;
case OpenVPN.ConnectionState.ERROR:
console.log('❌ VPN connection error - check configuration');
break;
}
});
// 🧹 Always clean up when component unmounts
subscription.remove();📥 Parameters:
callback: (state: ConnectionStateListenerCallback) => void
📤 Returns: EventSubscription
- Object with
remove()method to unsubscribe
📊 Callback Parameter Structure:
interface ConnectionStateListenerCallback {
state: ConnectionState; // Current connection state
}💡 Best Practices:
- ✅ Always call
subscription.remove()to prevent memory leaks - ✅ Use this for UI state updates (connection indicators, etc.)
- ✅ Handle all possible state values for robust UX
- ❌ Don't forget to unsubscribe when component unmounts
Complete TypeScript definitions for type-safe VPN integration
| 📝 Purpose | Main configuration interface for VPN connections |
| 🎯 Required | Username, password, platform options, and config |
| ⚡ Usage | Pass to connect() method |
interface ConnectionParams {
address?: string; // 🌐 VPN server address (optional if in config)
username: string; // 👤 Authentication username
password: string; // 🔑 Authentication password
openVPNConfig?: string; // 📄 Inline .ovpn config content
openVPNConfigLocalFile?: string; // 📁 Path to local .ovpn config file
iOSOptions: IOSConnectionOptions; // 🍎 iOS-specific configuration
androidOptions: AndroidConnectionOptions; // 🤖 Android-specific configuration
}✅ Required Fields:
| Field | Icon | Description |
|---|---|---|
username |
👤 | Username for VPN authentication |
password |
🔑 | Password for VPN authentication |
iOSOptions |
🍎 | iOS configuration (required even on Android) |
androidOptions |
🤖 | Android configuration (required even on iOS) |
⚙️ Configuration Options:
| Option | Priority | Description |
|---|---|---|
openVPNConfig |
🥇 High | Inline .ovpn config string (takes precedence) |
openVPNConfigLocalFile |
🥈 Medium | Local file path to .ovpn config |
address |
🥉 Low | Server address (optional if in config files) |
💡 Pro Tip: Either
openVPNConfigoropenVPNConfigLocalFilemust be provided. If both are given,openVPNConfigtakes precedence.
| 🏷️ Platform | iOS Specific |
| 📝 Purpose | Configure iOS Network Extension behavior |
| Required even when running on Android |
interface IOSConnectionOptions {
// 🔴 Required Fields
localizedDescription: string; // 📱 VPN connection description
networkExtensionBundleIdentifier: string; // 📦 Network extension bundle ID
disconnectOnSleep: boolean; // 😴 Disconnect when device sleeps
onDemandEnabled: boolean; // 🔄 Enable on-demand connection
// 🌐 Optional Network Settings
includeAllNetworks?: boolean; // 🌍 Route all traffic through VPN
excludeLocalNetworks?: boolean; // 🏠 Exclude local network traffic
excludeCellularServices?: boolean; // 📶 Exclude cellular services
excludeDeviceCommunication?: boolean; // 📱 Exclude device communication
// ⚙️ Optional Connection Behavior
persistTun?: boolean; // 🔒 Don't fallback when reconnecting
connectionTimeout?: number; // ⏱️ Connection timeout (seconds)
googleDNSFallback?: boolean; // 🌐 Use Google DNS as fallback
autologinSessions?: boolean; // 🔐 Allow autologin sessions
retryOnAuthFailed?: boolean; // 🔄 Retry on authentication failure
disableClientCert?: boolean; // 🚫 Don't send client certificate
forceCiphersuitesAESCBC?: boolean; // 🔐 Force AES-CBC cipher suites
}🔥 Example Configuration:
iOSOptions: {
// Required settings
localizedDescription: 'My Awesome VPN Connection',
networkExtensionBundleIdentifier: 'com.myapp.vpn-extension',
disconnectOnSleep: false,
onDemandEnabled: true,
// Network routing
includeAllNetworks: false, // Don't route ALL traffic
excludeLocalNetworks: true, // Keep local network access
// Connection behavior
persistTun: true, // More reliable reconnection
connectionTimeout: 30, // 30 second timeout
googleDNSFallback: true, // Fallback DNS for reliability
}💡 Configuration Tips:
- ✅
localizedDescriptionshows in iOS Settings → VPN - ✅
networkExtensionBundleIdentifiermust match your Xcode target exactly - ✅ Set
disconnectOnSleep: falsefor persistent connections - ✅ Enable
excludeLocalNetworksto access local devices (printers, etc.)
| 🏷️ Platform | Android Specific |
| 📝 Purpose | Comprehensive Android VPN configuration |
| Required even when running on iOS |
interface AndroidConnectionOptions {
// 🔴 Required
Notification: AndroidNotificationOptions; // 📲 Notification configuration
// 🔧 Internal Settings
useOpenVPN3?: boolean; // ⚡ Use OpenVPN3 SDK (experimental)
useSystemProxy?: boolean; // 🌐 Use system HTTP/HTTPS proxies
useReconnectOnNetworkChange?: boolean; // 🔄 Reconnect on network change
usePauseOnScreenOff?: boolean; // ⏸️ Pause VPN when screen off
useDisableConfirmDialog?: boolean; // 🚫 Disable disconnect dialogs
useProfileEncryption?: boolean; // 🔐 Encrypt VPN profiles
useKeepVPNConnected?: boolean; // 🔒 Keep connected on boot
// ⚙️ Basic Settings
compatibilityMode?: AndroidCompatibilityMode; // 🔧 OpenVPN compatibility mode
useLegacyProvider?: boolean; // 🔄 Load OpenSSL legacy provider
useLZOCompression?: boolean; // 📦 Use LZO compression
checkPeerFingerprint?: boolean; // 🔍 Check peer certificate fingerprint
peerFingerPrints?: string; // 🔒 Peer certificate fingerprints
// 🌐 Network Settings
pullSettings?: boolean; // ⬇️ Pull IP settings from server
ipv4?: string; // 🌐 Manual IPv4 (if pullSettings=false)
ipv6?: string; // 🌐 Manual IPv6 (if pullSettings=false)
noLocalBinding?: boolean; // 🚫 Don't bind local address/port
// 🌍 DNS Settings
overrideDNS?: boolean; // 🔄 Override DNS settings
searchDomain?: string; // 🔍 DNS search domain
DNS1?: string; // 🥇 Primary DNS server
DNS2?: string; // 🥈 Secondary DNS server
// 🗺️ Routing Settings
ignorePushedRoutes?: boolean; // 🚫 Ignore server-pushed routes
blockUnusedAddressFamilies?: boolean; // 🚫 Block unused IP families
allowLocalLAN?: boolean; // 🏠 Allow local LAN access
useDefaultRoute?: boolean; // 🌍 Route all IPv4 traffic
customRoutes?: string; // 🛣️ Custom IPv4 routes (CIDR)
excludedRoutes?: string; // 🚫 Excluded IPv4 routes (CIDR)
useDefaultRouteV6?: boolean; // 🌍 Route all IPv6 traffic
customRoutesV6?: string; // 🛣️ Custom IPv6 routes (CIDR)
excludedRoutesV6?: string; // 🚫 Excluded IPv6 routes (CIDR)
// 📱 App Routing
allowedVPNApps?: string[]; // ✅ Allowed app package names
allowedVPNAppsAreDisallowed?: boolean; // 🔄 Treat allowed apps as disallowed
allowAppVpnBypass?: boolean; // 🚫 Allow apps to bypass VPN
// 🔐 Security Settings
tlsProfileSecurity?: TLSSecurityProfile; // 🔒 TLS security profile
expectServerTLSCert?: boolean; // 📜 Expect server TLS certificate
certificateHostnameCheck?: boolean; // ✅ Check certificate hostname
remoteCertificateSubject?: string; // 📋 Remote certificate subject DN
remoteX509UsernameField?: string; // 👤 X509 username field
useTLSAuth?: boolean; // 🔐 Use TLS authentication
dataCiphers?: string; // 🔐 Encryption ciphers (colon-separated)
packetDigests?: string; // 🔐 Packet authentication (colon-separated)
// 🎛️ Client Behavior
persistTun?: boolean; // 🔒 Don't fallback when reconnecting
pushPeerInfo?: boolean; // 📤 Send extra info to server
useRandomHostname?: boolean; // 🎲 Add random chars to hostname
useFloat?: boolean; // 🌊 Allow packets from any IP
// ⚙️ Custom Configuration
useCustomConfig?: boolean; // 🛠️ Use custom options
customOptions?: string; // 📝 Custom OpenVPN options
// 🔄 Reconnection Settings
connectRetryMax?: string; // 🔢 Max retry attempts (-1 = unlimited)
connectRetryMaxTime?: string; // ⏱️ Max time between attempts (seconds)
connectRetry?: string; // ⏱️ Seconds between retries
}| 📝 Purpose | Configure Android VPN status notifications |
| 🎯 Features | Status updates, action buttons, connection timer |
| 💡 UX Impact | User can monitor and control VPN from notification |
interface AndroidNotificationOptions {
// 🔴 Required
openActivityPackageName: string; // 📦 Package name to open on tap
titleNotification: string; // 📱 Notification title
// 🎛️ Optional Actions
showDisconnectAction?: boolean; // 🔌 Show disconnect button
titleDisconnectButton?: string; // 🔌 Disconnect button text
showPauseAction?: boolean; // ⏸️ Show pause button (not supported)
titlePauseButton?: string; // ⏸️ Pause button text
titleResumeButton?: string; // ▶️ Resume button text
showTimer?: boolean; // ⏱️ Show connection timer
// 📱 Optional Status Messages
titleConnecting?: string; // 🟡 Connecting status text
titleConnected?: string; // 🟢 Connected status text
titleDisconnecting?: string; // 🟠 Disconnecting status text
titleDisconnected?: string; // 🔴 Disconnected status text
titlePaused?: string; // ⏸️ Paused status text
titleError?: string; // ❌ Error status text
}🔥 Example Configuration:
Notification: {
// Required settings
openActivityPackageName: 'com.myapp.MainActivity',
titleNotification: 'Secure VPN Connection',
// Status messages with emojis for better UX
titleConnected: '🔒 Secure Connection Active',
titleConnecting: '🔄 Establishing Secure Connection...',
titleDisconnecting: '🔄 Disconnecting from VPN...',
titleDisconnected: '🔓 VPN Disconnected',
titleError: '❌ VPN Connection Error',
// Action buttons
showDisconnectAction: true,
titleDisconnectButton: 'Disconnect VPN',
// Features
showTimer: true, // Shows connection duration
}💡 Notification Best Practices:
- ✅ Use clear, descriptive titles that indicate current status
- ✅ Include emojis for quick visual status recognition
- ✅ Enable
showTimerto show connection duration - ✅ Provide disconnect action for user convenience
Predefined constants for connection states and configuration options
| 📝 Purpose | VPN connection state enumeration |
| 🎯 Usage | State checking, UI updates, error handling |
| ⚡ Source | Returned by state methods and listeners |
enum ConnectionState {
DISCONNECTED = '0', // 🔴 Not connected to VPN
DISCONNECTING = '1', // 🟠 Disconnection in progress
CONNECTING = '2', // 🟡 Connection attempt in progress
CONNECTED = '3', // 🟢 Successfully connected
INVALID = '-1', // ⚪ Invalid/unknown state
ERROR = '-2', // ❌ Connection error occurred
}| State | Icon | Value | Description | Common Actions |
|---|---|---|---|---|
DISCONNECTED |
🔴 | '0' |
Not connected to VPN | Show "Connect" button |
DISCONNECTING |
🟠 | '1' |
Disconnection in progress | Show loading state |
CONNECTING |
🟡 | '2' |
Connection attempt in progress | Show loading state |
CONNECTED |
🟢 | '3' |
Successfully connected | Show "Disconnect" button |
INVALID |
⚪ | '-1' |
Invalid/unknown state | Refresh state |
ERROR |
❌ | '-2' |
Connection error occurred | Show error message |
💡 Usage Examples:
// In state change listener
const handleStateChange = (state) => {
switch (state.state) {
case OpenVPN.ConnectionState.CONNECTED:
setStatusIcon('🟢');
setButtonText('Disconnect');
setButtonEnabled(true);
break;
case OpenVPN.ConnectionState.CONNECTING:
setStatusIcon('🟡');
setButtonText('Connecting...');
setButtonEnabled(false);
break;
case OpenVPN.ConnectionState.DISCONNECTED:
setStatusIcon('🔴');
setButtonText('Connect');
setButtonEnabled(true);
break;
case OpenVPN.ConnectionState.ERROR:
setStatusIcon('❌');
setButtonText('Retry');
setButtonEnabled(true);
showErrorDialog('Connection failed');
break;
}
};
// In component render
const getStatusDisplay = (state) => {
const stateConfig = {
[ConnectionState.CONNECTED]: {
color: '#4CAF50',
text: 'Secure & Connected',
icon: '🔒'
},
[ConnectionState.CONNECTING]: {
color: '#FF9800',
text: 'Establishing Connection...',
icon: '⏳'
},
[ConnectionState.DISCONNECTED]: {
color: '#9E9E9E',
text: 'Not Connected',
icon: '🔓'
},
[ConnectionState.ERROR]: {
color: '#F44336',
text: 'Connection Error',
icon: '⚠️'
},
};
return stateConfig[state] || stateConfig[ConnectionState.INVALID];
};| 📝 Purpose | TLS security profile levels for encryption |
| 🎯 Usage | Configure Android TLS security strength |
| ⚡ Impact | Balances security vs compatibility |
enum TLSSecurityProfile {
INSECURE = 'insecure', // 🔓 Minimal security (not recommended)
LEGACY = 'legacy', // 🟡 Legacy compatibility mode
PREFERRED = 'preferred', // 🟢 Recommended security level
SUITEB = 'suiteb' // 🔒 High security Suite B profile
}| Profile | Icon | Security Level | Use Case | Recommendation |
|---|---|---|---|---|
INSECURE |
🔓 | Minimal | Development debugging only | ❌ Avoid in production |
LEGACY |
🟡 | Basic | Compatibility with old servers | |
PREFERRED |
🟢 | High | Modern deployments | ✅ Recommended default |
SUITEB |
🔒 | Maximum | High-security environments | ✅ Best for sensitive data |
🔥 Usage Example:
androidOptions: {
// Recommended for production
tlsProfileSecurity: TLSSecurityProfile.PREFERRED,
// For maximum security (government, healthcare, finance)
// tlsProfileSecurity: TLSSecurityProfile.SUITEB,
// For compatibility with legacy servers
// tlsProfileSecurity: TLSSecurityProfile.LEGACY,
}💡 Choosing the Right Profile:
- 🏢 Enterprise/Production: Use
PREFERREDfor best balance - 🏛️ High Security (Gov/Finance): Use
SUITEBfor maximum protection - 🔧 Legacy Systems: Use
LEGACYonly whenPREFERREDfails - 🚫 Never Use:
INSECUREexcept for local development debugging
| 📝 Purpose | OpenVPN compatibility modes for Android |
| 🎯 Usage | Ensure compatibility with different OpenVPN server versions |
| ⚡ Impact | Affects connection success with various server configs |
enum AndroidCompatibilityMode {
ModernDefaults = 0, // 🚀 Modern OpenVPN defaults
OpenVPN_2_5_x = 1, // 🔄 Compatible with OpenVPN 2.5.x
OpenVPN_2_4_x = 2, // 🔄 Compatible with OpenVPN 2.4.x
OpenVPN_2_3_x = 3, // 🔄 Compatible with OpenVPN 2.3.x
}| Mode | Icon | Server Version | Usage | Performance |
|---|---|---|---|---|
ModernDefaults |
🚀 | Latest OpenVPN | New servers with modern configs | ⚡ Best |
OpenVPN_2_5_x |
🔄 | 2.5.x series | Most current production servers | 🟢 Good |
OpenVPN_2_4_x |
🔄 | 2.4.x series | Common legacy deployments | 🟡 Fair |
OpenVPN_2_3_x |
🔄 | 2.3.x series | Very old servers | 🔴 Limited |
🔥 Usage Example:
androidOptions: {
// For most modern VPN providers (default)
compatibilityMode: AndroidCompatibilityMode.ModernDefaults,
// If connection fails, try stepping down:
// compatibilityMode: AndroidCompatibilityMode.OpenVPN_2_5_x,
// compatibilityMode: AndroidCompatibilityMode.OpenVPN_2_4_x,
// compatibilityMode: AndroidCompatibilityMode.OpenVPN_2_3_x,
}🎯 When to Use Each Mode:
| Server Scenario | Recommended Mode | Fallback Strategy |
|---|---|---|
| 🆕 New Server Setup | ModernDefaults |
If fails → OpenVPN_2_5_x |
| 🏢 Commercial VPN Service | OpenVPN_2_5_x |
If fails → OpenVPN_2_4_x |
| 🏛️ Corporate/Enterprise | OpenVPN_2_4_x |
If fails → OpenVPN_2_3_x |
| 🔧 Legacy Infrastructure | OpenVPN_2_3_x |
Consider server upgrade |
💡 Troubleshooting Connection Issues:
- Start with
ModernDefaults🚀 - If authentication fails → try
OpenVPN_2_5_x🔄 - If still failing → try
OpenVPN_2_4_x🔄 - Last resort → try
OpenVPN_2_3_x🔄 - If none work → check server configuration 🔧
Understanding iOS vs Android specific behaviors and requirements
| iOS requires a separate Network Extension target in Xcode | |
| 📦 Bundle ID | Must match networkExtensionBundleIdentifier exactly |
| 🏪 App Store | Special review process required for VPN apps |
// iOS Network Extension Configuration
iOSOptions: {
// 🎯 Must match your Network Extension bundle identifier exactly
networkExtensionBundleIdentifier: '<app-bundle>.OVPNEXT',
// 📝 Required for iOS App Store submissions
localizedDescription: 'Your App VPN Connection',
// ⚙️ iOS manages VPN connections at system level
disconnectOnSleep: false, // System may still override this
onDemandEnabled: true, // Automatic connection when needed
}| Limitation | Icon | Impact | Workaround |
|---|---|---|---|
| Simulator | 📱 | VPN doesn't work in simulator | Use physical device |
| Testing | 🧪 | Requires physical device | No simulator testing |
| App Store | 🏪 | Special VPN app review required | Prepare documentation |
| System Override | ⚙️ | iOS can override some settings | Handle gracefully |
| Background | 🔋 | May disconnect in background | Use on-demand connection |
💡 iOS Development Tips:
// Check if running on iOS and handle accordingly
if (Platform.OS === 'ios') {
// iOS-specific handling
console.log('🍎 Running on iOS - using Network Extension');
// iOS may disconnect in background
AppState.addEventListener('change', (nextAppState) => {
if (nextAppState === 'active') {
// Check VPN state when app becomes active
OpenVPN.requestCurrentState();
}
});
}| Explicit VPN permission must be granted | |
| 🎯 User Action | System dialog requires user confirmation |
| ⚡ One-Time | Permission persists until app uninstall |
// Always check/request permission on Android
if (Platform.OS === 'android') {
console.log('🤖 Android detected - checking VPN permissions');
const isPrepared = await OpenVPN.isPrepared();
if (!isPrepared) {
console.log('⏳ Requesting VPN permission...');
const granted = await OpenVPN.prepare(); // Shows system permission dialog
if (granted) {
console.log('✅ VPN permission granted');
} else {
console.log('❌ VPN permission denied by user');
// Handle permission denial
}
} else {
console.log('✅ VPN permission already granted');
}
}| Feature | Icon | Description | Benefit |
|---|---|---|---|
| Rich Notifications | 📲 | Actions, timer, status updates | Better UX control |
| Per-App Routing | 📱 | Route specific apps through VPN | Granular control |
| Custom DNS | 🌐 | Override DNS configuration | Enhanced privacy |
| Advanced Routing | 🛣️ | Custom routes, exclusions | Network flexibility |
| Multiple OpenVPN | ⚡ | Support for v2.x and v3.x | Broad compatibility |
🔥 Android Advanced Configuration:
androidOptions: {
// 📲 Rich notification system
Notification: {
openActivityPackageName: 'com.myapp.MainActivity',
titleNotification: '🔒 Secure VPN Active',
titleConnected: '✅ Protected Connection',
showDisconnectAction: true,
showTimer: true,
},
// 📱 Per-app VPN routing
allowedVPNApps: ['com.browser.app', 'com.email.app'],
allowAppVpnBypass: false,
// 🌐 Custom DNS configuration
overrideDNS: true,
DNS1: '8.8.8.8',
DNS2: '8.8.4.4',
// 🛣️ Network routing
allowLocalLAN: true,
useDefaultRoute: true,
excludedRoutes: '192.168.0.0/16,10.0.0.0/8',
// 🔄 Reconnection behavior
useReconnectOnNetworkChange: true,
connectRetryMax: '3',
connectRetry: '5',
}const connectVPN = async (config: ConnectionParams) => {
try {
console.log('🚀 Starting VPN connection...');
// 🤖 Android-specific permission check
if (Platform.OS === 'android') {
console.log('🔐 Checking Android VPN permissions...');
const isPrepared = await OpenVPN.isPrepared();
if (!isPrepared) {
console.log('⏳ Requesting VPN permission...');
const granted = await OpenVPN.prepare();
if (!granted) {
throw new Error('❌ VPN permission denied by user');
}
console.log('✅ VPN permission granted');
}
}
// 🔧 Configure for both platforms
const connectionConfig: ConnectionParams = {
...config,
iOSOptions: {
localizedDescription: 'My Secure VPN Connection',
networkExtensionBundleIdentifier: '<app-bundle>.OVPNEXT',
disconnectOnSleep: false,
onDemandEnabled: false,
excludeLocalNetworks: true,
persistTun: true,
...config.iOSOptions,
},
androidOptions: {
Notification: {
openActivityPackageName: 'com.myapp.MainActivity',
titleNotification: '🔒 VPN Connected',
titleConnected: '✅ Secure connection active',
titleConnecting: '⏳ Establishing connection...',
showDisconnectAction: true,
showTimer: true,
},
useReconnectOnNetworkChange: true,
allowLocalLAN: true,
...config.androidOptions,
},
};
console.log('🔗 Attempting VPN connection...');
await OpenVPN.connect(connectionConfig);
console.log('🎉 VPN connected successfully!');
} catch (error) {
console.error('❌ VPN connection failed:', error);
throw error;
}
};const VPNManager = {
// State change listener with platform considerations
setupStateListener: () => {
return OpenVPN.addOpenVPNStateChangeListener((state) => {
console.log(`📊 VPN state changed: ${state.state}`);
switch (state.state) {
case ConnectionState.CONNECTED:
console.log('🟢 VPN Connected');
if (Platform.OS === 'ios') {
// iOS may still disconnect in background
console.log('🍎 iOS: Connection active - may pause in background');
} else {
// Android has persistent notification
console.log('🤖 Android: Persistent connection with notification');
}
break;
case ConnectionState.DISCONNECTED:
console.log('🔴 VPN Disconnected');
if (Platform.OS === 'ios') {
// Check if intentional or system-caused
console.log('🍎 iOS: Check if disconnect was intentional');
}
break;
case ConnectionState.ERROR:
console.log('❌ VPN Error');
// Platform-specific error handling
VPNManager.handleConnectionError(state);
break;
}
});
},
// Platform-specific error handling
handleConnectionError: (state) => {
if (Platform.OS === 'android') {
// Android: Check permissions and retry
console.log('🤖 Android error - checking permissions...');
OpenVPN.isPrepared().then(prepared => {
if (!prepared) {
console.log('⚠️ VPN permission lost - re-request needed');
}
});
} else {
// iOS: May need to reconfigure Network Extension
console.log('🍎 iOS error - may need network extension reconfiguration');
}
},
};| Platform | Testing Environment | Key Considerations |
|---|---|---|
| 🍎 iOS | Physical device only | Xcode setup, App Store review |
| 🤖 Android | Emulator + Device | Permission flows, notifications |
| 🌐 Both | Real VPN servers | Network connectivity, configs |
💡 Universal Best Practices:
- ✅ Always check permissions - Especially on Android
- ✅ Validate configuration - Before attempting connection
- ✅ Implement proper error handling - Platform-specific responses
- ✅ Use state listeners - For real-time UI updates
- ✅ Test on physical devices - VPN requires real network
- ✅ Handle network changes - Graceful reconnection logic
- ✅ Consider background behavior - Platform differences
- ✅ Provide user feedback - Clear status and error messages
📚 Related Documentation:
- Installation Guide → - Platform setup and configuration
- Usage Examples → - Practical implementation examples
- Troubleshooting → - Common issues and solutions
💡 Pro Tips for Success:
- Start with the simplest configuration that works
- Test incrementally with different server configurations
- Always handle both success and error cases
- Use TypeScript for better development experience
- Monitor state changes for responsive UI updates
This comprehensive API reference covers all available methods, types, and platform-specific considerations. For hands-on examples and implementation guidance, explore the related documentation links above.