A VPN widget for the Omarchy bar. One icon shows whether you are behind a tunnel; one panel connects, disconnects, and switches between the VPN tools you actually have installed.
It supports Proton VPN, Mullvad, and the OpenVPN and WireGuard profiles NetworkManager holds. Only the tools found on your machine appear — install none and the widget tells you so; install several and a chip row lets you switch between them.
Each installed tool gets its own chip and its own view — Proton VPN above, Mullvad and NetworkManager below.
omarchy plugin add https://github.com/jkoestinger/omarchy-vpn.git
omarchy plugin enable jkoestinger.vpnPlugins land disabled so you can read the code before it runs — it runs
unsandboxed inside omarchy-shell, like every Omarchy plugin. Setup ›
Plugins does the same thing from the menu.
The icon appears at the right end of the bar. Move it with
omarchy bar move jkoestinger.vpn --before omarchy.clock, or any other
placement.
To update later: omarchy plugin update. To remove:
omarchy plugin remove jkoestinger.vpn.
The bar icon is dim when nothing is connected and bright when a tunnel is up. Hover it to see which one.
| Action | Result |
|---|---|
| Left click | Open the panel |
| Right click | Connect using the tool's own default, or disconnect |
| Middle click | Refresh status and public IP |
Inside the panel:
- Public IP sits top-left. Click it to copy it.
- The switch top-right connects or disconnects. Turning one VPN on shuts every other one off first — you never end up with two tunnels fighting over your routes.
- The chips below choose which tool you are looking at. They only appear when you have more than one installed.
- The name row is also a drawer. Tools with settings of their own get a chevron; click the row to fold them out, click it again to put them away. It starts closed and stays however you left it until the shell restarts.
- The settings inside are Mullvad's connect-on-startup, lockdown mode, and local network sharing, and Proton VPN's kill switch, NetShield, and port forwarding. They show what the tool itself reports, so changing one from its CLI shows up here on the next poll — the widget keeps no copy and never puts one back for you.
- The list is what you can connect to: for Proton VPN, fastest / P2P / random / Secure Core followed by every country; for Mullvad, any location followed by every country it has relays in; for NetworkManager, your OpenVPN and WireGuard profiles, told apart by their icon. A check mark marks where you are connected.
Keyboard, once the panel is open: j/k or arrows move — through the header,
the chips, the name row, the settings switches if they are open, then the list —
Enter connects, flips a switch, or opens and closes the settings drawer,
depending on what the cursor is on. h/l move along the chip row, s cycles
tools, / searches countries, d disconnects, r refreshes, Esc closes.
The public IP is fetched from checkip.amazonaws.com — never on a timer, only
when the connection changes, when the panel first opens, or when you ask.
Omarchy with its Quickshell desktop, plus at least one of:
- Proton VPN — the
protonvpnCLI, signed in (protonvpn signin). - Mullvad — the
mullvadCLI withmullvad-daemonrunning, logged in (mullvad account login <number>). - OpenVPN or WireGuard —
nmcli, plusopenvpnorwg(wireguard-tools), with at least one profile imported into NetworkManager.
Configure these in Setup › Plugins, or in the widget's entry in
~/.config/omarchy/shell.json.
| Setting | Default | What it does |
|---|---|---|
refreshIntervalSec |
15 |
How often the connection status is polled |
preferredBackend |
Auto |
Which tool the panel opens on. Auto picks whichever is connected |
favoriteCountries |
CH,NL,US |
Country codes pinned to the top of the Proton VPN and Mullvad lists |
Mullvad separates picking a relay from connecting: mullvad relay set location
records a constraint, mullvad connect brings the tunnel up against it. The
widget does both for you, so clicking a country connects to it and the choice
sticks — the switch and quickconnect reconnect to whatever you picked last
rather than to a "fastest server" the CLI has no notion of. Any location
hands the choice back to Mullvad.
Cities are searchable even though only countries are listed: typing zurich
finds Switzerland.
Lockdown mode blocks all traffic whenever Mullvad is disconnected — including the traffic another VPN needs to connect. The widget says so before it shuts Mullvad down for a different tool, but it will not turn lockdown off on its own. That switch is in the panel, or:
mullvad lockdown-mode set offNeither OpenVPN nor WireGuard has a daemon of its own to ask, so both come from NetworkManager — the thing that imports and stores tunnel configs on a desktop. They share one chip, and the row icon says which is which. Import one with:
nmcli connection import type openvpn file ~/Downloads/office.ovpn
nmcli connection import type wireguard file ~/Downloads/home.confA tunnel you started some other way is not listed: a bare openvpn process,
openvpn-client@.service, or a wg-quick@ unit. Neither is a tunnel another
tool on this list owns — Mullvad brings up its own WireGuard interface, and
NetworkManager adopts it, but that belongs on the Mullvad chip and appears only
there.
Picking a profile takes down whichever one is already up. NetworkManager is happy to run two tunnels at once; that is never what clicking a second profile means.
A freshly imported OpenVPN profile usually has no credentials saved, and there is no password prompt running inside the Omarchy shell. To make a profile connect in one click:
nmcli connection modify <name> +vpn.data username=<user>
nmcli connection modify <name> +vpn.data password-flags=0
nmcli connection modify <name> vpn.secrets 'password=<password>'password-flags=0 tells NetworkManager to own the password; imported profiles
usually arrive as 2 ("always ask"), which makes it ignore anything you saved.
The password then lives in /etc/NetworkManager/system-connections/, readable
by root only.
Without those, clicking a profile opens a terminal running
nmcli --ask connection up … so you can type the password there.
WireGuard needs none of this: its keys live in the profile. The one exception is
a profile whose wireguard.private-key-flags were set to ask an agent, which
lands in the same terminal.
If you are importing a Proton .ovpn: the username and password are the
OpenVPN/IKEv2 credentials from your Proton dashboard, not your Proton
account login.
"No username set" on a profile. NetworkManager keeps the OpenVPN username
outside the secrets store, so no password prompt can supply it. Set it with the
nmcli connection modify … +vpn.data username=<user> line above.
The server rejects credentials that look right. Check them against the
tool's own CLI first — for Proton, the OpenVPN credentials are not the account
password. journalctl -u NetworkManager -f shows AUTH_FAILED when the server
is the one saying no.
Mullvad says the daemon is not responding. The CLI is only a client. Start
the daemon with sudo systemctl start mullvad-daemon (and enable it to have it
come back after a reboot).
Nothing appears in the bar. Confirm the plugin is enabled with
omarchy plugin list, then omarchy restart shell.
Proton and NetworkManager fight each other. Proton's daemon tears down foreign tunnels when it connects. The widget already shuts other tools down before connecting, so use the widget rather than mixing it with the Proton app.
The widget answers on the shell's IPC bus, so keybindings and scripts can drive it:
omarchy-shell jkoestinger.vpn status # "Proton VPN · CH#1129 · Zurich, Switzerland"
omarchy-shell jkoestinger.vpn ip # current public address
omarchy-shell jkoestinger.vpn backends # "proton mullvad networkmanager"
omarchy-shell jkoestinger.vpn use mullvad # switch the panel's active tool
omarchy-shell jkoestinger.vpn connect CH # country code, profile name, or row key
omarchy-shell jkoestinger.vpn quickconnect # each tool's default connection
omarchy-shell jkoestinger.vpn disconnect
omarchy-shell jkoestinger.vpn toggle # open or close the panelAdding support for another VPN tool means writing one file. See ARCHITECTURE.md.
MIT. See LICENSE.


