Some Linux tools are attractive because they do less, clearly.
Impala is one of those tools: a keyboard-driven terminal interface for managing Wi-Fi on Linux, built around iwd.
If you already run NetworkManager, this is not a drop-in replacement for nmtui.
If you prefer iwd, minimalist systems, window managers, TTY workflows, or keyboard-first laptop setups, Impala gives you a friendlier layer over wireless management without pulling in a full desktop control panel.
Impala is a GPL-licensed Rust TUI for managing Wi-Fi on Linux with iwd.
Impala GitHub Source Code
iwd Project Wiki
Impala on crates.io
License: GPL-3.0
✅
What is Impala?
Impala is a terminal user interface for Wi-Fi management.
It can run in station mode for normal client Wi-Fi, or access point mode when your hardware and iwd setup support it.
The README highlights WPA Enterprise support, station and access point modes, QR-code network sharing, and hidden-network support.
The important prerequisite is explicit: Impala expects iwd to be running.
The project also warns that other wireless management services such as NetworkManager or wpa_supplicant should be disabled to avoid conflicts.
That is the main thing to understand before installing it on a daily laptop.
Why Use a TUI Wi-Fi Manager?
iwctl is already available when you use iwd.
It works, but it is still a command shell.
Impala gives you a discoverable interface:
- scan for nearby networks
- connect and disconnect
- manage known networks
- toggle autoconnect
- show adapter information
- power the wireless device on or off
- switch between station and access point modes
- share a known network through a QR code
- configure themes and keybindings
That makes it interesting for terminal-heavy Linux systems where you still want a quick visual overview of wireless state.
Tech Overview of Impala
Impala is a compact Rust application.
The current inspected release is v0.9.0, built from commit 7587092, with package version 0.9.0 in Cargo.toml.
The main stack:
| Layer | Technology |
|---|---|
| CLI | clap |
| Terminal UI | ratatui, crossterm, tui-input |
| Async runtime | tokio |
| Wireless backend | iwdrs |
| Config | serde, toml, dirs |
| Errors/logging | anyhow, log, env_logger |
| QR sharing | qrcode, tui-qrcode |
| Packaging | Cargo, GitHub Actions, Nix flake |
The architecture is easy to follow.
src/main.rs parses arguments, checks rfkill state, loads config, initializes the terminal, creates the iwd-backed app state, and runs the event loop. src/app.rs holds the top-level state: current focus, notifications, iwd session, adapter, device, auth state, reset state, and config.
Station mode lives under src/mode/station.rs and related submodules. Access point mode lives in src/mode/ap.rs. Keyboard behavior is centralized in src/handler.rs, while config defaults and theme parsing live in src/config.rs.
Installing Impala
Impala is not a Docker app.
It needs to control local wireless hardware through iwd, so install it on the Linux machine whose Wi-Fi you want to manage.
Prerequisites
You need:
- a Linux system
iwdinstalled and running- wireless hardware supported by iwd
- permissions to access iwd over D-Bus
- Nerd Fonts if you want icon rendering
Avoid running multiple Wi-Fi managers at the same time. If NetworkManager or wpa_supplicant is controlling the same interface, stop and disable the conflicting service before relying on Impala.
Warning: Do not stop NetworkManager or
wpa_supplicantwhile you are connected over Wi-Fi unless you have Ethernet, console access, or another recovery path. Switching the Wi-Fi backend to iwd can disconnect you before Impala is able to reconnect.
Install from crates.io with a current Rust toolchain:
cargo install impala
On Ubuntu 24.04/Noble, sudo apt install cargo installs Cargo/Rust 1.75, which is too old for Impala’s Rust edition 2024 manifest. Use rustup, the upstream release binary, Arch’s package, or Nix instead.
At the time of this field test, crates.io advertised impala = "0.8.1" while GitHub Releases had v0.9.0. If you need the newest GitHub tag immediately, use the release binary path.
Install Rust with rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
. "$HOME/.cargo/env"
rustup update stable
cargo install impala
Install on Arch Linux:
sudo pacman -S impala
Install with Nix:
nix-env -iA nixpkgs.impala
Build from source:
git clone https://github.com/pythops/impala.git
cd impala
cargo build --release

The release workflow also publishes static Linux binaries for x86_64 and aarch64 musl targets.
Ubuntu iwd Setup
On Ubuntu, install and start iwd first:
sudo apt install iwd
sudo systemctl enable --now iwd
systemctl status iwd
If you are testing on a machine currently connected by Ethernet, you can temporarily stop the conflicting Wi-Fi managers and launch Impala:
sudo systemctl stop NetworkManager
sudo systemctl stop wpa_supplicant
sudo systemctl restart iwd
sudo -E "$HOME/.cargo/bin/impala"
If you are connected only by Wi-Fi, do not run those stop commands from a remote session.
Get a cable, local keyboard/display, or another management path first.
Running Impala
Start in the default station mode:
impala
Start explicitly in station mode:
impala --mode station
Start in access point mode:
impala --mode ap
Use ASCII display if icons are not rendering cleanly:
impala --ascii
The CLI is intentionally small:
Options:
-m, --mode <mode> Device mode [possible values: station, ap]
--ascii Ascii display
-h, --help Print help
-V, --version Print version
Field Note: Build and Binary Smoke Test
I tested Impala in this workspace with the current repository checkout and the upstream v0.9.0 x86_64 static binary.
Local environment:
- Host architecture:
x86_64 - Rust:
rustc 1.75.0 - Cargo:
cargo 1.75.0 iwd: inactive- NetworkManager: active
The source build did not get past manifest parsing:
cargo build --release
Cargo returned:
feature `edition2024` is required
That is expected with an older Cargo because Impala uses Rust edition 2024. Ubuntu 24.04/Noble’s apt install cargo path currently installs Rust/Cargo 1.75, so it fails the same way. Use rustup, an upstream binary, an OS package with a newer Rust-built package, or Nix instead.
The upstream release binary worked for help/version:
curl -L --fail \
-o /tmp/impala-release/impala-x86_64-unknown-linux-musl \
https://github.com/pythops/impala/releases/download/v0.9.0/impala-x86_64-unknown-linux-musl
chmod +x /tmp/impala-release/impala-x86_64-unknown-linux-musl
/tmp/impala-release/impala-x86_64-unknown-linux-musl --help
/tmp/impala-release/impala-x86_64-unknown-linux-musl --version
It reported:
impala 0.9.0
After installing Rust with rustup, a reader-side install succeeded with rustc 1.98.0:
source "$HOME/.cargo/env"
cargo install impala
That installed impala v0.8.1 from crates.io. Running it then failed because iwd was not present on D-Bus:
Can not access the iwd service.
Error: org.freedesktop.DBus.Error.ServiceUnknown: The name net.connman.iwd was not provided by any .service files
That means the binary installed correctly, but the local wireless backend is not ready. A full test should be done on a Linux machine where iwd is installed, running, and owns the wireless interface.
A follow-up test succeeded after installing and starting iwd, but it also confirmed the practical warning above: switching away from NetworkManager while connected via Wi-Fi can drop the active connection. In that test, Ethernet was needed to continue after the Wi-Fi handoff.
Configuration
Impala reads its config from:
$HOME/.config/impala/config.toml
If the file does not exist, defaults are used.
The README shows configurable keybindings and theme colors:
ascii = false
switch = "r"
mode = "station"
esc_quit = false
[device]
infos = "i"
toggle_power = "o"
[access_point]
start = "n"
stop = "x"
[station]
toggle_scanning = "s"
[station.known_network]
toggle_autoconnect = "t"
remove = "d"
show_all = "a"
share = "p"
[station.new_network]
show_all = "a"
connect_hidden = "n"
[theme]
background = "dark gray"
border = "green"
text_color = "white"
hidden_color = "dark gray"
info_color = "green"
warning_color = "yellow"
error_color = "red"
Version 0.9.0 added configurable colors, so this is worth revisiting if you tried older Impala builds and wanted better terminal-theme integration.
Impala vs iwctl, nmtui, and NetworkManager
Pick Impala if:
- you use iwd directly
- you want a terminal UI instead of remembering
iwctlcommands - you run a window manager, TTY-first setup, or lightweight Linux desktop
- you want AP mode and station mode in one TUI
- you like Rust terminal tools with small configuration files
Use iwctl if:
- you want the lowest-level iwd control surface
- you are debugging iwd itself
- you need a command-first workflow for scripts or recovery environments
Use NetworkManager tools if:
- your distro desktop already depends on NetworkManager
- you need VPN, WWAN, wired profiles, enterprise desktop policy, or broad GUI integration
- you do not want to switch your Wi-Fi backend to iwd
The critical distinction is backend ownership. Impala is for iwd-managed Wi-Fi. NetworkManager users should not install it expecting it to control NetworkManager profiles.
Conclusion
Impala is a focused tool for a focused setup: Linux Wi-Fi management through iwd, from the terminal.
That makes it a good fit for keyboard-first users who want a nicer interface than raw iwctl, while still keeping the stack lean. The source is also readable: Ratatui for UI, Crossterm for terminal events, Tokio for async work, and iwdrs for the wireless backend.
The main caution is operational, not architectural. Make sure iwd is the service controlling Wi-Fi, make sure your Rust toolchain is new enough if building from source, and do not run it against a NetworkManager-owned interface expecting clean results.
FAQ
Is Impala a NetworkManager TUI?
No. Impala is built for iwd.
If you use NetworkManager, use NetworkManager’s own tools such as nmcli or nmtui, or deliberately migrate the wireless interface to iwd first.
Does Impala need Docker?
No. Docker is the wrong model here.
Impala manages local Wi-Fi hardware through iwd, so it should run directly on the Linux host.
Why does building Impala fail with edition2024?
Your Rust/Cargo toolchain is too old for this project.
The inspected checkout uses Rust edition 2024. Upgrade Rust, use an OS package, install through Nix, or download an upstream release binary.
Can Impala manage hidden networks and WPA Enterprise?
Yes. The README lists hidden-network support and WPA Enterprise support, and the source contains explicit authentication flows for EAP-style networks.
Real compatibility still depends on iwd, driver support, and your network’s authentication settings.
Can Impala run on a server?
Only if that server is a Linux machine with Wi-Fi hardware managed by iwd.
For most headless servers, Impala is less relevant than direct iwctl, systemd-networkd/iwd configuration, or NetworkManager automation.
Recovery FAQ: Getting Wi-Fi Back After Testing Impala
What happened during the real recovery test?
The machine started on regular Ubuntu desktop networking with NetworkManager. Installing Impala through Ubuntu’s apt install cargo path failed because Ubuntu Noble ships Rust/Cargo 1.75, which is too old for Impala’s Rust edition 2024 manifest.
After installing Rust with rustup, cargo install impala worked and installed impala v0.8.1 from crates.io. Running impala then failed because the iwd D-Bus service was missing:
Can not access the iwd service.
Error: org.freedesktop.DBus.Error.ServiceUnknown: The name net.connman.iwd was not provided by any .service files
Installing and starting iwd fixed that part, but stopping NetworkManager while connected over Wi-Fi dropped the active connection. The recovery continued over Ethernet.
How do I install Impala on Ubuntu without the old Cargo problem?
Do not rely on Ubuntu 24.04/Noble’s apt install cargo if you plan to build Impala from crates.io. Use rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
rustup update stable
rustc --version
cargo --version
cargo install impala
In the field test, rustup provided rustc 1.98.0, and cargo install impala completed.
How do I install and start iwd for Impala?
Install iwd and start the service:
sudo apt install iwd
sudo systemctl enable --now iwd
systemctl status iwd
Then try Impala:
source "$HOME/.cargo/env"
sudo -E "$HOME/.cargo/bin/impala"
If Impala still says it cannot access net.connman.iwd, check the service:
systemctl is-active iwd
journalctl -u iwd -n 80 --no-pager
What command can disconnect my Wi-Fi?
This is the risky handoff:
sudo systemctl stop NetworkManager
sudo systemctl stop wpa_supplicant
sudo systemctl restart iwd
sudo -E "$HOME/.cargo/bin/impala"
Only run it if you have Ethernet connected, local console access, or another recovery path. If your laptop is connected only through Wi-Fi, stopping NetworkManager can drop the connection before you have a working iwd/Impala session.
How do I switch back from iwd to regular NetworkManager Wi-Fi?
Use this to hand Wi-Fi back to the regular NetworkManager + wpa_supplicant path:
sudo systemctl stop iwd
sudo systemctl disable iwd
sudo systemctl unmask NetworkManager wpa_supplicant
sudo systemctl enable --now NetworkManager
sudo systemctl enable --now wpa_supplicant
sudo systemctl restart NetworkManager
nmcli radio wifi on
Then check status:
nmcli device status
nmcli radio
rfkill list
If Wi-Fi is blocked:
sudo rfkill unblock wifi
nmcli radio wifi on
What if rfkill sees phy0 but nmcli says WIFI-HW missing?
In the field recovery, rfkill list showed phy0, but NetworkManager had no usable Wi-Fi interface:
WIFI-HW WIFI
missing enabled
The diagnostic commands were:
ip link | grep -E 'wl|wlan|wifi|^[0-9]+:'
sudo apt install iw
iw dev
ls /sys/class/net
iw dev was empty, and no wl* interface existed under /sys/class/net. Creating a managed interface from phy0 brought Wi-Fi back into NetworkManager:
sudo iw phy phy0 interface add wlan0 type managed
sudo ip link set wlan0 up
sudo systemctl restart NetworkManager
nmcli device status
nmcli radio
After that, nmcli device status showed:
wlan0 wifi disconnected --
That is progress: the Wi-Fi interface exists again and can scan.
How do I rescan and reconnect after wlan0 appears?
Rescan on the recreated interface:
nmcli device wifi rescan ifname wlan0
nmcli device wifi list ifname wlan0
List saved profiles:
nmcli connection show
Try the saved profile:
nmcli connection up "Piszymsiu" ifname wlan0
If NetworkManager says the profile is not compatible because the interface names do not match, the saved connection is pinned to the old interface name.
How do I fix a saved Wi-Fi profile pinned to the old interface name?
Inspect the saved profile:
nmcli -f connection.interface-name,802-11-wireless.mac-address connection show "Piszymsiu"
In the field recovery, the profile was pinned to:
connection.interface-name: wlp3s0
The recreated interface was wlan0, so NetworkManager refused to activate the profile. Clear the pinned interface and MAC restriction:
sudo nmcli connection modify "Piszymsiu" connection.interface-name ""
sudo nmcli connection modify "Piszymsiu" 802-11-wireless.mac-address ""
Then retry:
nmcli connection up "Piszymsiu" ifname wlan0
What if NetworkManager says Wi-Fi secrets were not provided?
After clearing the pinned interface, NetworkManager may need the Wi-Fi password again:
Secrets were required, but not provided
Use --ask:
nmcli connection up "Piszymsiu" ifname wlan0 --ask
Enter the normal Wi-Fi password when prompted. In the field recovery, this successfully activated the Wi-Fi connection:
Connection successfully activated
You can also set the password explicitly:
sudo nmcli connection modify "Piszymsiu" wifi-sec.key-mgmt wpa-psk
sudo nmcli connection modify "Piszymsiu" wifi-sec.psk "YOUR_WIFI_PASSWORD"
nmcli connection up "Piszymsiu" ifname wlan0
How do I verify Wi-Fi and Ethernet independently?
Check active connections:
nmcli connection show --active
nmcli device status
ip addr show wlan0
Verify Wi-Fi specifically:
ping -I wlan0 -c 3 1.1.1.1
ping -I wlan0 -c 3 google.com
Verify Ethernet specifically. In the field recovery, the USB Ethernet device was enx00e04c361dbf:
ping -I enx00e04c361dbf -c 3 1.1.1.1
ping -I enx00e04c361dbf -c 3 google.com
See which connection is the default route:
ip route | grep default
Example:
default via 192.168.8.1 dev enx00e04c361dbf metric 100
default via 192.168.1.1 dev wlan0 metric 600
Lower metric wins, so normal traffic uses Ethernet in that example. Wi-Fi is still connected and usable as fallback.
Check which DNS servers each interface received:
resolvectl dns wlan0
resolvectl dns enx00e04c361dbf
Show complete DNS/link details:
resolvectl status wlan0
resolvectl status enx00e04c361dbf
NetworkManager can show the same DHCP-provided DNS values:
nmcli device show wlan0 | grep -E 'IP4.DNS|IP6.DNS|GENERAL.DEVICE|GENERAL.CONNECTION'
nmcli device show enx00e04c361dbf | grep -E 'IP4.DNS|IP6.DNS|GENERAL.DEVICE|GENERAL.CONNECTION'
Test DNS resolution through each interface:
resolvectl query google.com -i wlan0
resolvectl query google.com -i enx00e04c361dbf
What final settings should I keep after recovery?
Once Wi-Fi works again, make the normal NetworkManager setup persistent:
sudo nmcli connection modify "Piszymsiu" connection.autoconnect yes
sudo nmcli connection modify "Piszymsiu" connection.interface-name ""
sudo systemctl disable iwd
sudo systemctl enable NetworkManager
sudo systemctl enable wpa_supplicant
Keep Ethernet connected until Wi-Fi has an IP address and these pass:
ping -I wlan0 -c 3 1.1.1.1
ping -I wlan0 -c 3 google.com
After that, unplug Ethernet and confirm the default route moves to Wi-Fi:
ip route | grep default
ping -c 3 1.1.1.1
Comments