Skip to content

junaidk/wgtui

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

wgtui

A terminal UI for monitoring WireGuard peers. It joins human-readable peer names from your config file with live runtime stats from wg show, and presents them in a clean, auto-refreshing table.

  WireGuard · wg0    4 peers  ·  updated 0s ago
╭───────────────┬───────────┬────────────────────┬─────────────────────────┬───────────┬───────────────────────╮
│ Name          │ Status    │ Endpoint           │ Allowed IPs             │ Handshake │ Transfer (↓rx / ↑tx)  │
├───────────────┼───────────┼────────────────────┼─────────────────────────┼───────────┼───────────────────────┤
│ bob.van       │ ● online  │ 203.0.113.10:51820 │ 10.0.0.2/32             │ 12s ago   │ ↓1.2 MiB ↑514.0 KiB   │
│ alice.johnson │ ● online  │ 198.51.100.7:48123 │ 10.0.0.3/32, 10.0.0.4/32│ 1m ago    │ ↓942.0 MiB ↑117.8 MiB │
│ carol.smith   │ ● offline │ 192.0.2.55:51820   │ 10.0.0.5/32             │ 14m ago   │ ↓40.1 MiB ↑8.0 MiB    │
│ dave.lee      │ ● never   │ —                  │ 10.0.0.6/32             │ never     │ ↓0 B ↑0 B             │
╰───────────────┴───────────┴────────────────────┴─────────────────────────┴───────────┴───────────────────────╯
r refresh · q quit

The ● online / ● offline / ● never markers are colored green / amber / grey.

Why

wg show is raw and, crucially, does not show human-readable peer names — those live only as comments in the config file:

[Peer]
# bob.van
PublicKey = aB1cD2eF3gH4iJ5kL6mN7oP8qR9sT0uV1wX2yZ3aB4=
AllowedIPs = 10.0.0.2/32

wgtui reads that comment, matches it to the peer by public key, and shows the name alongside live status, endpoint, handshake age, and transfer counters.

Install

go install wgtui/cmd/wgtui@latest   # or: make install

Requires Go 1.26+.

Usage

wgtui -i wg0          # monitor interface wg0 (default)
wgtui --demo          # synthetic data — no WireGuard needed

Reading WireGuard state and the config file usually requires elevated privileges:

sudo wgtui -i wg0

Flags

Flag Default Description
-i wg0 WireGuard interface to monitor
-config /etc/wireguard/<iface>.conf Path to the interface config (for names)
--demo false Use synthetic data; runs without WireGuard

Keys

Key Action
r Refresh now
q / Ctrl+C Quit

The table also auto-refreshes every 2 seconds.

Columns

  • Name — from the # name comment in the config (falls back to a short public-key prefix if unnamed).
  • Status● online (green) if a handshake occurred within the last 3 minutes, ● offline (amber) otherwise, ● never (grey) if the peer has never connected.
  • Endpoint — the peer's remote ip:port.
  • Allowed IPs — the peer's configured allowed IP ranges (comma-separated).
  • Handshake — relative age of the latest handshake.
  • Transfer — bytes received (↓) and sent (↑), human-readable.

How it works

Data access sits behind a small Provider interface, so the UI is decoupled from the source:

  • CommandProvider shells out to wg show <iface> dump and reads the config file for names — the production path.
  • FakeProvider returns synthetic peers — powers --demo and the tests.

The parsers are pure functions, so the entire test suite runs without WireGuard installed.

cmd/wgtui/         entry point + flags
internal/wg/       peer model, config & dump parsers, providers
internal/ui/       Bubble Tea model, columns, Lipgloss theme
testdata/          sample config + dump fixtures

Built with the Charm stack: Bubble Tea (event loop) and Lipgloss + lipgloss/table (rendering).

Development

make            # build into ./bin
make demo       # run the TUI with synthetic data
make test       # run all tests
make snapshot   # print a rendered demo frame
make check      # vet + test
make cross      # cross-compile for all platforms into ./dist
make help       # list all targets

Cross-compilation targets linux/{amd64,arm64} and darwin/{amd64,arm64} by default (override with make cross PLATFORMS="linux/amd64 windows/amd64"). Builds are static (CGO_ENABLED=0) and reproducible (-trimpath). Since wg/wg-quick are Linux-native, the Linux builds are the primary deployment target; the rest are handy for --demo and local development.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors