- Go 97.5%
- Nix 1.2%
- Makefile 0.7%
- Shell 0.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .github/workflows | ||
| docs | ||
| internal | ||
| .envrc | ||
| .gitignore | ||
| .SRCINFO | ||
| flake.lock | ||
| flake.nix | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| main.go | ||
| main_test.go | ||
| Makefile | ||
| PKGBUILD | ||
| README.md | ||
| VERSION | ||
nmt
A terminal UI for managing Wi-Fi with NetworkManager, built with bubbletea.
Features
- List nearby networks with signal strength, security, and channel
- Scan on demand (
r) - Connect to networks — reuses saved profiles automatically, only prompts for a password when the network has no saved profile yet
- Disconnect (
d), forget saved networks (f) - Saved networks view (
F): manage every Wi-Fi profile, including ones out of range — connect, toggle autoconnect, change the password, forget - Toggle Wi-Fi radio on/off (
t) - Live status bar: radio state, active connection, IP, and interface
- Filter the network list (
/) and sort it (o): signal, name, channel, or security - Network details (
i): BSSID, channel, frequency, rate, mode and security - Speed test the active connection (
s): ping + 10s download + 10s upload against Cloudflare, with live progress;Sruns a quick 5s + 5s test (stdlib only, no extra dependencies) - Connect to hidden networks by SSID (
h) - Multiple Wi-Fi devices: switch the managed interface (
D) - Headless
status/list/speedtestcommands with--jsonoutput - Config file for interface, polling, sorting and speed test defaults
- Mouse wheel scrolling
Requirements
- Linux with NetworkManager (
networkmanagerpackage on Arch) nmcliin$PATH- An active session (polkit grants Wi-Fi management without root on desktop sessions like KDE)
Build
go build -o bin/nmt .
Or use the Makefile, which injects the version from VERSION and has targets
for building, installing (with the man page) and checking:
make build # binary at ./bin/nmt
make install # to /usr/local/bin/nmt
Reproducible build with Nix
flake.nix pins nixpkgs and the Go toolchain through flake.lock, so every
build uses an identical dependency set regardless of the host system:
nix build # binary at ./result/bin/nmt
nix flake check # builds the package and runs the test suite in the sandbox
nix run . # run the TUI straight from the flake
If you use direnv, direnv allow once — every shell in
this directory then automatically uses the pinned dev shell (Go 1.27, gopls,
make) via nix-direnv:
direnv allow
go version # reports the toolchain from the flake, not the system
make build # or: make check (vet + tests), make run, make install
Usage
nmt [flags] # TUI
nmt status [--json]
nmt list [--json] [--rescan] [--interface <name>]
nmt speedtest [--json] [--quick] [--server <url>] [--duration <d>] [--streams <n>]
nmt version
nmt help
Flags
| Flag | Description |
|---|---|
-i, --interface <name> |
Wi-Fi interface to manage (e.g. wlan0) |
-v, --version |
Print version information and exit |
-h, --help |
Show help information and exit |
Headless commands
status, list and speedtest run without a terminal and support --json
for scripts:
nmt status --json | jq -r .connection
nmt list --json | jq -r '.[] | select(.in_use) | .ssid'
nmt speedtest --quick --json
Keybindings
| Key | Action |
|---|---|
↑/k ↓/j |
navigate networks |
enter |
connect |
r |
rescan |
t |
toggle Wi-Fi on/off |
d |
disconnect current network |
f |
forget selected network's saved profile |
i |
show network details |
o |
cycle sort order (signal → name → channel → security) |
F |
saved networks view |
h |
connect to a hidden network by SSID |
D |
switch Wi-Fi device (multi-NIC) |
/ |
filter networks |
s |
speed test active connection |
S |
quick speed test (5s down + 5s up) |
ctrl+r |
show/hide password (at the password prompt) |
esc |
clear active filter / dismiss message / cancel a pending action |
q / ctrl+c |
quit |
In the saved networks view:
| Key | Action |
|---|---|
↑/k ↓/j |
navigate profiles |
enter |
connect to the selected profile |
a |
toggle autoconnect |
e |
change the saved password |
f |
forget the profile |
r |
reload the profile list |
esc / F |
back to the network list |
Configuration
Settings are read from $XDG_CONFIG_HOME/nmt/config (usually
~/.config/nmt/config). The format is key = value, # starts a comment:
interface = wlan0 # optional; auto-detected when unset
poll_interval = 5s
sort = signal # signal | name | channel | security
speedtest_server = https://speed.cloudflare.com
speedtest_duration = 10s
speedtest_streams = 4
speedtest_quick = false
Precedence: command-line flags > environment variables > config file >
defaults. Environment: NMT_CONFIG (config path), NMT_INTERFACE,
NMT_POLL_INTERVAL, NMT_SPEEDTEST_SERVER. Unknown keys and invalid values
are ignored with a warning.
Notes
- If a saved profile has a stale password, connect will fail; press
F, select the profile and presseto update the password in place, orfto forget the profile and connect again. - Hidden networks appear as
(hidden network). Presshto join one by SSID; the profile is then saved normally and shows up in the list.
Layout
main.go entry point, flags and headless subcommands
internal/config/ key=value config file loader
internal/nm/ nmcli wrapper (exec, terse-mode parsing, actions)
internal/speedtest/ stdlib HTTP speed test (ping + timed download/upload)
internal/ui/ bubbletea model, keybindings, styles