terminal ui to control wifi
  • Go 97.5%
  • Nix 1.2%
  • Makefile 0.7%
  • Shell 0.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Vaibhav Sijaria 2836b383b8
Some checks failed
ci / test (push) Has been cancelled
ci / nix (push) Has been cancelled
Bump version to 0.4.0
2026-09-10 19:00:57 +05:30
.github/workflows chore: install as nmt, single-source the version, add man page 2026-09-10 18:47:35 +05:30
docs Bump version to 0.4.0 2026-09-10 19:00:57 +05:30
internal chore: install as nmt, single-source the version, add man page 2026-09-10 18:47:35 +05:30
.envrc Add direnv integration for the dev shell 2026-08-31 23:23:09 +05:30
.gitignore chore: install as nmt, single-source the version, add man page 2026-09-10 18:47:35 +05:30
.SRCINFO Bump version to 0.4.0 2026-09-10 19:00:57 +05:30
flake.lock Add nix flake for reproducible builds 2026-08-31 23:23:08 +05:30
flake.nix chore: install as nmt, single-source the version, add man page 2026-09-10 18:47:35 +05:30
go.mod Scaffold Go module and nmcli wrapper with terse-mode parser 2026-08-31 22:12:12 +05:30
go.sum Scaffold Go module and nmcli wrapper with terse-mode parser 2026-08-31 22:12:12 +05:30
LICENSE Add MIT license 2026-08-31 22:12:41 +05:30
main.go chore: install as nmt, single-source the version, add man page 2026-09-10 18:47:35 +05:30
main_test.go feat: key=value config file and headless subcommands 2026-09-10 18:41:49 +05:30
Makefile chore: install as nmt, single-source the version, add man page 2026-09-10 18:47:35 +05:30
PKGBUILD chore: install as nmt, single-source the version, add man page 2026-09-10 18:47:35 +05:30
README.md chore: install as nmt, single-source the version, add man page 2026-09-10 18:47:35 +05:30
VERSION Bump version to 0.4.0 2026-09-10 19:00:57 +05:30

nmt

ci

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; S runs 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/speedtest commands with --json output
  • Config file for interface, polling, sorting and speed test defaults
  • Mouse wheel scrolling

Requirements

  • Linux with NetworkManager (networkmanager package on Arch)
  • nmcli in $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 press e to update the password in place, or f to forget the profile and connect again.
  • Hidden networks appear as (hidden network). Press h to 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