tauri-plugin-network-manager 2.1.2

A Tauri plugin to manage network connections using networkmanager and systemd-networkd.
Documentation

Tauri Network Manager Plugin

Linux-first Tauri plugin to manage network state, Wi-Fi and VPN through NetworkManager over D-Bus.

Features

  • Read current network state
  • List available Wi-Fi networks
  • Connect and disconnect Wi-Fi
  • List and delete saved Wi-Fi connections
  • Enable or disable networking and wireless
  • Check wireless adapter availability
  • Read network stats and available interfaces
  • List VPN profiles
  • Read current VPN status
  • Connect and disconnect VPN profiles
  • Create, update and delete VPN profiles
  • Listen to network and VPN change events (network-changed, vpn-changed, vpn-connected, vpn-disconnected, vpn-failed)

Requirements

  • Linux with NetworkManager running
  • Tauri 2
  • Rust 1.77.2+

Installation

Rust dependency

Add the plugin crate to your Tauri app:

[dependencies]
tauri-plugin-network-manager = { git = "https://github.com/Vasak-OS/tauri-plugin-network-manager" }

Register the plugin in your Tauri builder.

NPM package

Install the JS guest bindings:

bun add @vasakgroup/plugin-network-manager

Permissions (Tauri capabilities)

The default permission set includes:

  • network-manager:allow-get-network-state
  • network-manager:allow-list-wifi-networks
  • network-manager:allow-rescan-wifi
  • network-manager:allow-connect-to-wifi
  • network-manager:allow-disconnect-from-wifi
  • network-manager:allow-get-saved-wifi-networks
  • network-manager:allow-delete-wifi-connection
  • network-manager:allow-toggle-network-state
  • network-manager:allow-get-wireless-enabled
  • network-manager:allow-set-wireless-enabled
  • network-manager:allow-is-wireless-available
  • network-manager:allow-list-vpn-profiles
  • network-manager:allow-get-vpn-status

Mutating VPN operations are intentionally excluded from default permissions.

To enable VPN management operations, add the dedicated permission set:

  • network-manager:vpn_management

This set includes:

  • network-manager:allow-connect-vpn
  • network-manager:allow-disconnect-vpn
  • network-manager:allow-create-vpn-profile
  • network-manager:allow-update-vpn-profile
  • network-manager:allow-delete-vpn-profile

Types exposed in NPM

The package exports these TypeScript types:

  • NetworkInfo
  • NetworkStats
  • WiFiSecurityType
  • WiFiConnectionConfig (Rust wire format)
  • ConnectToWifiInput (frontend-friendly format)
  • ListWifiNetworksOptions
  • VpnType
  • VpnConnectionState
  • VpnProfile
  • VpnStatus
  • VpnEventPayload
  • VpnCreateInput
  • VpnUpdateInput
  • NetworkManagerErrorCode
  • NetworkManagerError

Security type values

WiFiSecurityType values are:

  • none
  • wep
  • wpa-psk
  • wpa-eap
  • wpa2-psk
  • wpa3-psk

VPN type values

VpnType values are:

  • open-vpn
  • wire-guard
  • l2tp
  • pptp
  • sstp
  • ikev2
  • fortisslvpn
  • open-connect
  • generic

API reference

State and scan

  • getCurrentNetworkState(): Promise<NetworkInfo>
  • listWifiNetworks(options?: ListWifiNetworksOptions): Promise<NetworkInfo[]>
  • rescanWifi(): Promise<NetworkInfo[]>
  • getSavedWifiNetworks(): Promise<NetworkInfo[]>

Wi-Fi connection management

  • connectToWifi(config: ConnectToWifiInput | WiFiConnectionConfig): Promise<void>
  • disconnectFromWifi(): Promise<void>
  • deleteWifiConnection(ssid: string): Promise<void>

VPN profile and connection management

  • listVpnProfiles(): Promise<VpnProfile[]>
  • getVpnStatus(): Promise<VpnStatus>
  • connectVpn(uuid: string): Promise<void>
  • disconnectVpn(uuid?: string): Promise<void>
  • createVpnProfile(config: VpnCreateInput): Promise<VpnProfile>
  • updateVpnProfile(config: VpnUpdateInput): Promise<VpnProfile>
  • deleteVpnProfile(uuid: string): Promise<void>

Radio and networking toggles

  • toggleNetwork(enabled: boolean): Promise<void>
  • getWirelessEnabled(): Promise<boolean>
  • setWirelessEnabled(enabled: boolean): Promise<void>
  • isWirelessAvailable(): Promise<boolean>

Stats

  • getNetworkStats(): Promise<NetworkStats>
  • getNetworkInterfaces(): Promise<string[]>

Usage examples (TypeScript)

Wi-Fi

import {
  connectToWifi,
  deleteWifiConnection,
  disconnectFromWifi,
  getCurrentNetworkState,
  getSavedWifiNetworks,
  listWifiNetworks,
  WiFiSecurityType,
} from '@vasakgroup/plugin-network-manager';

async function wifiFlow() {
  const state = await getCurrentNetworkState();
  console.log('Current network:', state);

  const available = await listWifiNetworks();
  console.log('Available Wi-Fi:', available.map((n) => n.ssid));

  await connectToWifi({
    ssid: 'OfficeWiFi',
    password: 'secret-password',
    securityType: WiFiSecurityType.WPA2_PSK,
  });

  const saved = await getSavedWifiNetworks();
  console.log('Saved Wi-Fi:', saved.map((n) => n.ssid));

  await disconnectFromWifi();
  await deleteWifiConnection('OldNetwork');
}

wifiFlow().catch(console.error);

VPN

import {
  connectVpn,
  createVpnProfile,
  disconnectVpn,
  getVpnStatus,
  listVpnProfiles,
  updateVpnProfile,
  deleteVpnProfile,
} from '@vasakgroup/plugin-network-manager';

async function vpnFlow() {
  const profile = await createVpnProfile({
    id: 'Office VPN',
    vpn_type: 'wire-guard',
    autoconnect: false,
    settings: {
      mtu: '1420',
      remote: 'vpn.example.com:51820',
    },
    secrets: {
      private_key: '***',
    },
  });

  console.log('Created profile:', profile);

  const profiles = await listVpnProfiles();
  console.log('Profiles:', profiles.map((p) => `${p.id} (${p.uuid})`));

  await connectVpn(profile.uuid);
  console.log('VPN status after connect:', await getVpnStatus());

  const updated = await updateVpnProfile({
    uuid: profile.uuid,
    autoconnect: true,
  });
  console.log('Updated profile:', updated);

  await disconnectVpn(profile.uuid);
  await deleteVpnProfile(profile.uuid);
}

vpnFlow().catch(console.error);

Listening to VPN events

import { listen } from '@tauri-apps/api/event';
import type { VpnEventPayload } from '@vasakgroup/plugin-network-manager';

const unlistenChanged = await listen<VpnEventPayload>('vpn-changed', (event) => {
  console.log('VPN changed:', event.payload.status.state);
});

const unlistenConnected = await listen<VpnEventPayload>('vpn-connected', (event) => {
  console.log('VPN connected:', event.payload.profile?.id);
});

const unlistenFailed = await listen<VpnEventPayload>('vpn-failed', (event) => {
  console.error('VPN failed:', event.payload.reason);
});

// call unlistenChanged(), unlistenConnected(), unlistenFailed() when no longer needed

Typed errors

All exported async functions throw a typed NetworkManagerError with a code in case of invoke failure.

Common Wi-Fi and generic codes:

  • NOT_INITIALIZED
  • NO_CONNECTION
  • PERMISSION_DENIED
  • UNSUPPORTED_SECURITY
  • CONNECTION_FAILED
  • NETWORK_NOT_FOUND
  • OPERATION_FAILED

VPN-specific codes:

  • VPN_PROFILE_NOT_FOUND
  • VPN_ALREADY_CONNECTED
  • VPN_AUTH_FAILED
  • VPN_INVALID_CONFIG
  • VPN_ACTIVATION_FAILED
  • VPN_PLUGIN_UNAVAILABLE
  • VPN_NOT_ACTIVE

Fallback code:

  • UNKNOWN

Package exports and types

The package is published with ESM + CJS bundles and declaration files:

  • main: ./dist-js/index.cjs
  • module: ./dist-js/index.js
  • types: ./dist-js/index.d.ts
  • exports.types: ./dist-js/index.d.ts
  • exports.import: ./dist-js/index.js
  • exports.require: ./dist-js/index.cjs

Notes

  • connectToWifi accepts both formats:
    • frontend-friendly: { securityType: ... }
    • Rust wire-format: { security_type: ... }
  • The wrapper maps frontend input to the command payload expected by Rust.
  • listWifiNetworks supports cache control:
    • forceRefresh: bypasses cache
    • ttlMs: cache TTL in milliseconds

Testing and build

Build package:

bun run build

Run smoke tests:

bun run test