narsil 0.2.0

A terminal-based system resource monitor โ€” GPU-aware, Braille charts, per-char label inversion
narsil-0.2.0 is not a library.

A terminal-based system resource monitor written in Rust โ€” fast, readable, and GPU-aware.

Named after the reforged sword of Aragorn, narsil is built to be sharper than the tools that came before it. It targets developers and power users who live in the terminal and need real-time system insight without leaving it.

Platform support โ€” narsil runs on Linux, Windows, and macOS. The GPU tab (AMD/NVIDIA) is Linux-only for now; all other tabs work on every supported OS.


๐Ÿ“ธ Screenshot

narsil screenshot


โœจ Features

Current scope (v0.1)

Tab What you see Platform
๐Ÿ—บ๏ธ Overview CPU gauge, RAM gauge, live RX/TX sparklines, top processes (fills available height) all
๐Ÿง  CPU Global usage history chart (Braille), per-core gauges with colour-coded load all
๐Ÿ’พ Memory RAM + Swap history charts, GiB usage gauges all
๐ŸŒ Network Combined RX/TX history chart, per-direction current throughput all
๐Ÿ’ฟ Disks Per-partition usage bars at fixed height, scrollable when partitions exceed the terminal all
๐Ÿ”ฌ Processes Process table sorted by CPU, scrollable, fills available height all
๐ŸŽฎ GPU Per-GPU cards with utilisation + VRAM history charts, gauges, temperature and power draw Linux only

๐Ÿ”‘ Key behaviours

  • ๐ŸŽจ Split-colour gauges โ€” the percentage label rendered inside every gauge automatically inverts its colour character-by-character at the fill boundary so it is always readable, even when the bar is exactly at 50%.
  • ๐Ÿ“œ Scroll indicators โ€” any panel that cannot display all items at once shows โ–ฒ/โ–ผ/โ–ฒโ–ผ in its title.
  • ๐Ÿ“ Dynamic sizing โ€” all panels adapt to the current terminal dimensions; no hard-coded row counts.
  • โšก Configurable refresh rate โ€” pass --interval <ms> on startup (default 1 000 ms) to tune between low-latency and low-CPU usage; key events are processed between ticks with zero busy-waiting.
  • โŒจ๏ธ Keyboard-first navigation: Tab / Shift+Tab wrap-around tab switching; 1โ€“6 direct jump (1โ€“7 on Linux); j/k or arrow keys for scrolling; q or Ctrl-C to quit.
  • ๐Ÿ’ฌ Status bar โ€” persistent one-line keybinding reference at the bottom, context-aware per tab.

๐Ÿš€ Installation

Prerequisites

  • Linux, Windows 10+, or macOS 12+
  • GPU tab requires Linux with standard /sys mounts and amdgpu (AMD) or NVIDIA proprietary drivers
  • Rust toolchain โ‰ฅ 1.85 โ€” needed only for cargo install or source builds (rustup update stable)

Official release channels

Channel Platforms Standard NVIDIA variant
crates.io all cargo install narsil cargo install narsil --features nvidia
AUR Arch Linux narsil ยท narsil-bin narsil-nvidia ยท narsil-nvidia-bin
AppImage Linux x86_64 narsil-{ver}-x86_64.AppImage narsil-nvidia-{ver}-x86_64.AppImage
Windows zip Windows x86_64 narsil-{ver}-x86_64-windows.zip narsil-nvidia-{ver}-x86_64-windows.zip
Linux tarball Linux x86_64 narsil-{ver}-x86_64.tar.gz narsil-nvidia-{ver}-x86_64.tar.gz
Source all cargo build --release cargo build --release --features nvidia

AppImage, Windows zip, and Linux tarball are attached to every GitHub release.

crates.io

cargo install narsil                      # standard
cargo install narsil --features nvidia    # with NVIDIA GPU support (Linux only)

AUR (Arch Linux)

Four packages are published to the AUR:

Package Type Description
narsil source standard, compiled from the crates.io source tarball
narsil-nvidia source like narsil but built with --features nvidia
narsil-bin binary standard, installs prebuilt tarball from GitHub Releases
narsil-nvidia-bin binary NVIDIA variant, installs prebuilt tarball from GitHub Releases
yay -S narsil              # standard, built from source
yay -S narsil-nvidia       # with NVIDIA GPU support, built from source
yay -S narsil-bin          # standard, prebuilt binary
yay -S narsil-nvidia-bin   # with NVIDIA GPU support, prebuilt binary

AppImage (Linux x86_64)

Download from the latest GitHub release, make executable and run:

chmod +x narsil-*-x86_64.AppImage
./narsil-*-x86_64.AppImage

Two variants per release: narsil-{version}-x86_64.AppImage (standard) and narsil-nvidia-{version}-x86_64.AppImage (with NVIDIA support).

Windows (x86_64)

Download narsil-{version}-x86_64-windows.zip or narsil-nvidia-{version}-x86_64-windows.zip from the latest GitHub release, extract, and run narsil.exe in PowerShell or cmd.

The GPU tab is not compiled into the Windows build.

Linux tarball (x86_64)

Download from the latest GitHub release:

tar xzf narsil-{version}-x86_64.tar.gz
./narsil-{version}/narsil

Both standard and NVIDIA variants are available.

Build from source

git clone https://github.com/Pommersche92/narsil
cd narsil
cargo build --release
./target/release/narsil        # Linux / macOS
.\target\release\narsil.exe    # Windows

# With NVIDIA GPU support (Linux only):
cargo build --release --features nvidia

๐ŸŽฎ GPU support matrix

GPU monitoring is Linux-only. On Windows and macOS the GPU tab is not compiled in; all other tabs work normally.

Vendor Driver Detected Utilisation Memory Temperature Power
๐Ÿ”ด AMD discrete amdgpu โœ… โœ… gpu_busy_percent โœ… VRAM โœ… hwmon โœ… hwmon
๐Ÿ”ด AMD iGPU (APU) amdgpu โœ… โœ… โš ๏ธ GTT (shared RAM) โœ… โœ…
๐ŸŸข NVIDIA proprietary + --features nvidia โœ… โœ… NVML โœ… NVML โœ… NVML โœ… NVML
๐Ÿ”ต Intel iGPU i915 / xe โŒ โ€” โ€” โ€” โ€”
๐Ÿ”ต Intel Arc discrete xe โŒ โ€” โ€” โ€” โ€”

โš ๏ธ AMD APU note: the VRAM figures reflect GTT memory (system RAM dynamically assigned to the GPU), not dedicated video memory. The values are accurate but on-screen labels will stay as "VRAM" until the display is updated in a future release.

๐Ÿ—“๏ธ Intel note: Intel GPU support is planned โ€” see Roadmap below.


โŒจ๏ธ Keybindings

Key Action Platform
Tab / Shift+Tab Next / previous tab (wraps around) all
1 โ€“ 6 Jump directly to tab all
7 Jump to GPU tab Linux only
โ†’ / l Next tab all
โ† / h Previous tab all
โ†“ / j Scroll down (Disks, Processes; + GPU on Linux) all
โ†‘ / k Scroll up all
q / Ctrl-C Quit all

๐Ÿ—๏ธ Architecture

src/
โ”œโ”€โ”€ main.rs               โ€” terminal setup, raw-mode lifecycle, event + tick loop
โ”œโ”€โ”€ app.rs                โ€” App state dispatcher: calls each metrics::refresh on every tick
โ”œโ”€โ”€ metrics/
โ”‚   โ”œโ”€โ”€ mod.rs            โ€” HISTORY_LEN constant, push_history helper, re-exports
โ”‚   โ”œโ”€โ”€ cpu.rs            โ€” CpuState, per-core + global history
โ”‚   โ”œโ”€โ”€ memory.rs         โ€” MemState, RAM + swap
โ”‚   โ”œโ”€โ”€ network.rs        โ€” NetState, RX/TX rates and history
โ”‚   โ”œโ”€โ”€ disks.rs          โ€” DiskState, per-partition usage
โ”‚   โ”œโ”€โ”€ processes.rs      โ€” ProcessEntry, top-100 by CPU
โ”‚   โ””โ”€โ”€ gpu/
โ”‚       โ”œโ”€โ”€ mod.rs        โ€” GpuEntry, vendor dispatch
โ”‚       โ”œโ”€โ”€ amd.rs        โ€” sysfs-based AMD metrics
โ”‚       โ””โ”€โ”€ nvidia.rs     โ€” NVML-based NVIDIA metrics (feature-gated)
โ””โ”€โ”€ ui/
    โ”œโ”€โ”€ mod.rs            โ€” draw() entry point
    โ”œโ”€โ”€ helpers.rs        โ€” format_bytes, usage_color, scroll_indicator
    โ”œโ”€โ”€ statusbar.rs      โ€” persistent keybinding bar
    โ”œโ”€โ”€ tab_bar.rs        โ€” tab header row
    โ”œโ”€โ”€ widgets/
    โ”‚   โ””โ”€โ”€ split_gauge.rs โ€” SplitGauge custom widget
    โ””โ”€โ”€ tabs/
        โ”œโ”€โ”€ overview.rs   โ€” combined overview tab
        โ”œโ”€โ”€ cpu.rs
        โ”œโ”€โ”€ memory.rs
        โ”œโ”€โ”€ network.rs
        โ”œโ”€โ”€ disks.rs
        โ”œโ”€โ”€ processes.rs
        โ””โ”€โ”€ gpu.rs

Data flows in one direction:

app.on_tick()  โ†’  App (shared state)  โ†’  ui::draw()  โ†’  ratatui frame

There is no async runtime; crossterm::event::poll provides the non-blocking event check.


๐Ÿงช Testing

The test suite lives in src/tests/ and is compiled only in test builds (#[cfg(test)]). It covers the full public API: metric structs, refresh functions, UI helpers, and the SplitGauge widget.

cargo test

Test coverage overview

Module What is tested
tests::push_history Ring-buffer eviction, growth to capacity, length invariant
tests::helpers format_bytes SI boundaries, usage_color/_f64 thresholds, scroll_indicator states
tests::cpu CpuState::new zeroed state & history dimensions; refresh valid range & history cap
tests::memory MemState::new zeroed state; refresh used โ‰ค total + history cap
tests::network NetState::new zeroed state; refresh history cap & rate consistency
tests::disks DiskState field storage; refresh non-empty result, used โ‰ค total, non-empty names/mounts
tests::processes ProcessEntry field storage; refresh โ‰ค 100 entries, CPU-descending sort, non-empty names
tests::gpu GpuEntry::new zeroed fields, history lengths; amd::refresh smoke test & invariants
tests::split_gauge Ratio clamping, full/empty/half fill, label centring, block inner area, zero-size no-panic

Running with NVIDIA feature

cargo test --features nvidia

๐Ÿ“ฆ Dependencies

Crate Purpose
ratatui TUI layout and widget rendering
crossterm Cross-platform terminal control, raw mode, event stream
sysinfo CPU, RAM, swap, network, disk, process data
anyhow Ergonomic error handling
nvml-wrapper (optional) NVIDIA GPU metrics via NVML

๐Ÿ—บ๏ธ Roadmap

Items are loosely ordered by priority.

๐Ÿ”œ Near-term

  • ๐Ÿ”ต Intel GPU support โ€” utilisation via GT frequency ratio (i915/xe sysfs), LMEM for Intel Arc cards, temperature via hwmon; shown with appropriate caveats for iGPUs
  • ๐Ÿท๏ธ AMD APU label fix โ€” distinguish GTT (shared) from dedicated VRAM and label accordingly
  • โฑ๏ธ Configurable refresh rate โ€” CLI flag --interval <ms> to tune between low-latency and low-CPU usage โœ…
  • ๐ŸŽจ Colour themes โ€” built-in dark/light/high-contrast theme switcher

๐Ÿ”ง Medium-term

  • ๐Ÿ”ฌ Per-process GPU attribution โ€” show which processes hold GPU memory (via NVML or fdinfo on the DRM driver)
  • ๐ŸŒก๏ธ Temperature history charts โ€” per-core CPU and GPU temperature sparklines, not just current values
  • ๐Ÿ’จ Fan speed โ€” hwmon fan RPM display in the GPU card and a new thermal overview section
  • ๐ŸŒ Network per-interface breakdown โ€” drill-down view listing each interface (eth0, wlan0, loโ€ฆ) separately with its own sparkline
  • ๐Ÿ’ฝ Disk I/O throughput โ€” read/write MB/s per device, not just partition usage percentages
  • ๐Ÿ”‹ Battery / power panel โ€” laptop-focused: charge level, rate of charge/discharge, estimated time remaining

๐Ÿš€ Long-term / differentiators

  • ๐Ÿ“‹ Log tail panel โ€” a dedicated tab that tails systemd journal or a user-specified log file in real time, with regex highlight rules; something htop and gotop completely lack
  • ๐Ÿšจ Alert rules โ€” user-defined thresholds (e.g. CPU > 90% for > 5 s, VRAM > 80%) that flash the affected panel border red and optionally send a desktop or webhook notification
  • ๐Ÿ”Œ Plugin / script hooks โ€” allow arbitrary shell scripts or Rust dynamic libraries to provide custom metric panels, making narsil extensible without a fork
  • ๐Ÿ“ผ Session recording & replay โ€” record a metric session to a compact binary file and replay it later for post-mortem analysis
  • ๐Ÿ–ฅ๏ธ SSH-aware remote mode โ€” connect to a remote host via SSH and display its metrics locally in the same TUI, without needing narsil installed on the remote
  • ๐Ÿ–ฑ๏ธ Mouse support โ€” click tabs and scroll panels with the mouse alongside the existing keyboard navigation
  • ๐Ÿ“Š Export โ€” one-shot --json / --prometheus output mode for integration with external dashboards (Grafana etc.)

โš–๏ธ Comparison with existing tools

Feature top htop gotop narsil
Language C C Go ๐Ÿฆ€ Rust
GPU metrics โŒ โŒ partial โœ… AMD + NVIDIA (Linux)
Braille charts โŒ โŒ โœ… โœ…
Per-char label inversion โŒ โŒ โŒ โœ…
Disk usage bars โŒ โŒ โœ… โœ…
Status bar with keybindings โŒ โŒ โŒ โœ…
Log tail panel โŒ โŒ โŒ ๐Ÿ—“๏ธ planned
Alert rules โŒ โŒ โŒ ๐Ÿ—“๏ธ planned
Remote mode โŒ โŒ โŒ ๐Ÿ—“๏ธ planned
Session replay โŒ โŒ โŒ ๐Ÿ—“๏ธ planned

๐Ÿ“„ License

GPL-3.0 โ€” see LICENSE.