hw-monitor is a Linux desktop application designed to monitor various aspects of your computer's hardware. Built with the Tauri framework, it pairs a Rust backend with a TypeScript/React frontend.
The app is organised around five main sections:
Detailed information about each process running on the machine. Processes can be sorted, searched, and viewed as a flat list or a hierarchical tree. Each process displays its own icon fetched from installed .desktop files. The columns shown:
- User
- PID
- PPID
- Name
- State
- Memory Usage
- CPU Usage
- Total Disk Read
- Total Disk Write
- Disk Read Speed
- Disk Write Speed
Live graphs of key hardware components (CPU, RAM, GPU, disks, and network interfaces) with full detail panels next to each graph.
Name, socket, core/thread/live-thread counts, base/current/maximum speed, virtualisation flag, VM/hypervisor detection, uptime, temperature, and per-level cache sizes (L1d, L1i, L2, L3).
Live totals (total, free, available, cached, active, swap) plus hardware information read via udevadm, no root required:
- Speed: configured transfer speed in MT/s
- Slots Used: populated vs total memory slots
- Form Factor: e.g. SODIMM, DIMM
- Type: e.g. DDR4, DDR5
NVIDIA cards via NVML and AMD cards via sysfs: name, driver version, memory totals, temperature, utilisation, clock speed, wattage, fan speed, performance state.
Per-interface upload/download speeds, totals transferred, MAC, IPv4/IPv6 addresses, link speed, connection state, interface type, WiFi signal strength, and RX/TX errors and drops. Virtual interfaces are hidden by default and can be toggled from the config panel.
Every sensor exposed under /sys/class/hwmon is auto-detected and grouped by chip. Each sensor row shows its current reading, an optional heat bar relative to its critical threshold, and a status badge (normal, warning, or critical).
For each individual sensor you can:
- open a live graph modal plotting recent history;
- override the displayed label;
- set custom warning and critical thresholds;
- hide the sensor (toggle "Show hidden" in the toolbar to see hidden ones again).
On laptops, a battery box surfaces cycle count, technology, energy, time-to-full/time-to-empty, temperature, state-of-health, and current charge.
A lsblk-style tree of disks and partitions, with a usage bar for each mounted partition. Live per-disk read/write speeds and IOPS update alongside the layout.
Selecting a disk opens a details modal with the full picture pulled from /sys/block:
- model, vendor, serial, firmware revision, WWID, transport;
- queue parameters (depth, schedulers, read-ahead, max sectors, write cache, FUA, DAX, zoned);
- discard and TRIM behaviour;
- aggregate I/O counters and queue stats;
- SMART data for both ATA and NVMe drives, covering overall health, attribute table, power-on hours, temperature, reallocated/pending/uncorrectable sectors (ATA) and critical warnings, available spare, percentage used, power cycles, unsafe shutdowns, media errors, data units read/written (NVMe).
Lists all systemd services on the system with their load state, active state, sub-state, and unit-file state. Services can be searched and sorted by any column.
Selecting a service reveals an action bar with Start, Stop, and Restart. Performing any action opens an in-app password dialog, no terminal required. The password is passed only to sudo -S systemctl for the requested action, is not stored by hw-monitor, and errors (including a wrong password) surface directly in the UI.
Every TCP and UDP socket in the machine's network namespace, read directly from /proc/net/tcp, /proc/net/tcp6, /proc/net/udp, and /proc/net/udp6. The columns shown:
- Protocol (
tcp,tcp6,udp,udp6) - Local address and port
- Remote address and port
- State (the full TCP state machine, plus
UNCONNfor bound datagram sockets) - PID and process name
- User
Sockets are matched to the process holding them by resolving socket inodes through /proc/[pid]/fd. Reading another user's descriptors requires privileges, so an unprivileged run attributes only your own sockets and leaves the rest blank, the same way ss(8) and netstat(8) behave; the table says so rather than silently showing an empty column.
The list can be searched across every field and filtered by protocol (TCP/UDP) and by state (listening or established). Any column sorts, with addresses ordered by octet and ports ordered numerically rather than as text. Selecting a row reveals its full endpoints, owning UID, socket inode, and receive/send queue depths.
The application ships with eight languages: Arabic, German, English, Spanish, French, Polish, Russian, and Ukrainian. Switch from the configuration panel.
Three presets bundle with the app and can be switched from the config panel:
- Default: neutral dark slate
- Catppuccin: Mocha palette
- Gruvbox: classic warm dark
Every individual colour, update interval, and visible table column is editable from the config panel. The in-app picker is the source of truth, and edits persist to ~/.config/hw-monitor/hw-monitor.conf. The bundled presets live in src/components/Config/themes.ts; new presets added there are validated automatically by npm run check:themes (palette completeness, valid hex values, monotonic heatbar gradient, foreground/background contrast).
The app creates a configuration file at startup at ~/.config/hw-monitor/hw-monitor.conf. It can be managed via the built-in GUI or edited by hand. The config persists:
- every section's colour palette;
- per-section update intervals;
- the visible Processes columns;
- the selected language;
- per-sensor preferences (hidden IDs, custom labels, custom warning/critical thresholds);
- the "show virtual network interfaces" toggle.
git clone https://aur.archlinux.org/hw-monitor.git
cd hw-monitor
makepkg -siOr with an AUR helper:
yay -S hw-monitorDownload the .deb package from the releases page and install it:
sudo dpkg -i hw-monitor_<version>_amd64.deb
sudo apt-get install -f # resolve any missing dependenciesIf the app fails to start with a missing shared-library error such as:
error while loading shared libraries: libjavascriptcoregtk-4.1.so
install the WebKit2GTK 4.1 package for your distribution:
| Distribution | Command |
|---|---|
| Arch Linux | sudo pacman -S webkit2gtk-4.1 |
| Debian/Ubuntu | sudo apt install libwebkit2gtk-4.1-dev |
| Fedora/RHEL | sudo dnf install webkit2gtk4.1-devel |
| Gentoo | sudo emerge --ask net-libs/webkit-gtk:4.1 |
| Void Linux | sudo xbps-install -S webkit2gtk-devel |
Managing system services also requires polkit and a running desktop
authentication agent (policykit-1 on Debian/Ubuntu, polkit on most other
distributions). Passwords are entered only in the native polkit dialog and are
never sent through the application's webview or IPC layer.
If you use an NVIDIA GPU and encounter errors like:
GBM-DRV error (nv_gbm_create_device_native): nv_common_gbm_create_device failed
Failed to create GBM buffer of size 800x600: Permission denied
add these environment variables to your shell config (.bashrc, .zshrc, or config.fish):
export WEBKIT_DISABLE_DMABUF_RENDERER=1
export LIBGL_ALWAYS_SOFTWARE=1
export QT_XCB_FORCE_SOFTWARE_OPENGL=1For fish:
set -Ux WEBKIT_DISABLE_DMABUF_RENDERER 1
set -Ux LIBGL_ALWAYS_SOFTWARE 1
set -Ux QT_XCB_FORCE_SOFTWARE_OPENGL 1-
Clone the repository:
git clone https://github.com/husseinhareb/hw-monitor cd hw-monitor -
Install frontend dependencies:
npm install
-
Run in development mode (auto-regenerates the Rust to TS bindings):
npm run tauri dev
-
Build a release binary:
npm run tauri build
npm run check:bindings: verifysrc/bindings.tsis in sync with the Rust command models.npm run check:themes: validate the bundled theme presets (palette completeness, valid hex, monotonic heatbar gradient, foreground/background contrast).npm run typecheck: run the TypeScript compiler without emitting files.npm run lint: lint JavaScript, TypeScript, and React hook usage.npm test: run the frontend regression tests.
- feat: disk details modal exposing full
/sys/blockmetadata (model, vendor, serial, firmware, WWID, transport, schedulers, queue depth, read-ahead, write cache, FUA, DAX, TRIM, discard limits) - feat: SMART data for ATA and NVMe drives (overall health, attribute table, power-on hours, temperature, reallocated/pending/uncorrectable sectors, NVMe wear, available spare, media errors, data units read/written)
- feat: per-sensor live graph modal plotting recent history
- feat: per-sensor controls (hide/show, custom label, custom warning/critical thresholds, filter)
- feat: system tray icon with Open/Quit menu, close-to-tray instead of close-to-quit
- feat: service startup management (enable/disable systemd units)
- feat: recent service logs displayed inside the service details panel
- feat: detailed network interface panel (MAC, IPv4/IPv6, link speed, type, WiFi signal, RX/TX errors and drops)
- feat: theme integrity validator (
npm run check:themes) wired into CI - feat: frontend bindings auto-generated from Rust command models (
npm run check:bindings, predev/prebuild hooks) - feat: dedicated CI workflow (rustfmt, clippy, backend tests, bindings check, theme check, frontend build)
- fix: Catppuccin and Gruvbox heatbars re-tuned to be palette-correct and strictly monotonic, no duplicate stops
- fix: Gruvbox contrast bumped on performance title, value, and disk-name colours
- fix: sensor graph modal now follows the configured foreground and title colours
- fix: disk details modal width widened for readability
- fix: multiple sensor and disk modal styling regressions
- fix: replaced
polisheddependency with a small in-treesafeLightenhelper - fix:
zbusdependency dropped, all data now read via direct sysfs and procfs
- fix: memory hardware info (speed, slots, form factor, type) now reads via
udevadm info, no root required - fix: services start/stop/restart errors are now properly surfaced in the UI
- fix: process icons now visible in production builds (CSP
data:URI fix) - feat: GUI password dialog for service management, no terminal prompt needed
- feat: Services section: list, search, sort, start/stop/restart systemd services
- feat: memory hardware info panel (speed, slots used, form factor, type)
- feat: CPU details: live thread count, VM/hypervisor detection, cache sizes
- feat: theme selector in config panel (Default, Catppuccin, Gruvbox)
- fix: unknown config keys are skipped instead of crashing
- fix: i18n fully awaited before first render
- fix: responsive graph height and config dropdown layout
- feat: multilingual support (Arabic, German, English, Spanish, French, Polish, Russian, Ukrainian)
- feat: process tree view
- feat: per-core CPU graphs
- feat: GPU monitoring (NVIDIA via NVML, AMD via sysfs)
- feat: disk performance graphs
Contributions are welcome.
- Fork the repository.
- Create a branch:
git checkout -b feature/YourFeature - Commit your changes:
git commit -m 'Add some feature' - Push to the branch:
git push origin feature/YourFeature - Submit a pull request.
Please run npm run check:bindings and npm run check:themes before opening a PR. Both are enforced in CI alongside cargo fmt --check, cargo clippy -D warnings, and cargo test.
This project is licensed under the MIT License.