Skip to main content

Frontend Architectures

Mullvad VPN provides multiple frontend applications across different platforms, all communicating with the same core daemon. Each platform has unique requirements and communication patterns.

Communication Mechanisms

Desktop: gRPC over Unix Domain Socket

Platforms: Linux, macOS, Windows (named pipe) The desktop Electron app and CLI communicate with the daemon via gRPC defined in mullvad-management-interface/proto/management_interface.proto.
Key features:
  • Bidirectional streaming for event subscriptions
  • Multiple concurrent clients supported
  • Connection-oriented (clients detect daemon restarts)
  • Automatic reconnection handling in clients

Android: JNI (Java Native Interface)

Platform: Android On Android, the daemon runs in the same process as the VpnService, with the Kotlin/Java UI layer calling into Rust via JNI.
Communication pattern:
  • Synchronous JNI calls from Java to Rust for commands
  • Callbacks from Rust to Java for events (via JNI)
  • Daemon initialized in VpnService.onCreate()
  • Tunnel file descriptor passed from Android VpnService to Rust
Example JNI interface:

iOS: Custom Integration with WireGuard-Kit

Platform: iOS iOS uses a different architecture where the tunnel is managed by Apple’s WireGuard-kit, with Mullvad logic providing account management and relay selection.
Key differences from other platforms:
  • No full daemon running; WireGuard-kit handles tunnel
  • Mullvad Rust code provides relay selection and account logic
  • Network extension runs in separate process from main app
  • Uses iOS NEPacketTunnelProvider API
  • Offline detection via NWPathMonitor

Frontend-Specific Architectures

Desktop Electron App

Location: desktop/packages/mullvad-vpn/ Architecture:
Key features:
  • React for UI rendering
  • Redux for state management
  • Electron IPC between renderer and main process
  • Main process maintains persistent gRPC connection to daemon
  • Automatic reconnection on daemon restart
  • System tray integration for quick access
  • Auto-update using Mullvad’s update system
State synchronization:
  1. Main process subscribes to daemon event stream
  2. Events forwarded to renderer via Electron IPC
  3. Redux store updated with new state
  4. React components re-render

Android App

Location: android/ Architecture:
Android-specific considerations:
  • VpnService.Builder API for creating VPN tunnel
  • Always-on VPN support
  • Split tunneling using Android app UIDs
  • Per-app VPN configuration
  • ConnectivityManager for offline detection
  • Background service lifecycle management
  • Notification requirement for foreground service
Tunnel file descriptor flow:
  1. Android VpnService.Builder creates tunnel interface
  2. Tunnel FD passed to Rust via JNI
  3. Rust daemon uses FD for WireGuard tunnel
  4. Traffic routed through VPN by Android system

iOS App

Location: ios/ Architecture:
iOS-specific architecture:
  • Separate process for network extension
  • App Groups for shared data between app and extension
  • WireGuard-kit provides tunnel implementation
  • Mullvad Rust code compiled as static library
  • NWPathMonitor for network reachability
  • Keychain for secure credential storage
Communication between app and extension:
  • Shared app group container for settings
  • File-based communication for configuration
  • XPC for limited IPC

CLI (Command-Line Interface)

Location: mullvad-cli/ Architecture:
Features:
  • Complete feature parity with GUI
  • Scriptable interface
  • JSON output mode for programmatic use
  • Same gRPC interface as desktop app
  • Single command execution (not interactive)
Example commands:

Event Subscription Pattern

All frontends follow a similar pattern for receiving state updates:

Desktop/CLI (gRPC)

Android (JNI Callbacks)

Platform-Specific Features

Desktop

  • System tray integration
  • Launch at startup
  • Auto-updater
  • Local network sharing settings
  • Split tunneling (Linux, Windows, macOS)

Android

  • Always-on VPN
  • Per-app VPN
  • Tile for quick connect
  • Work profile support
  • Split tunneling by app

iOS

  • On-demand VPN rules
  • VPN configuration profile
  • Siri shortcuts
  • Widget support

CLI

  • Scriptable automation
  • JSON output format
  • Batch operations
  • Server administration