A fast, cyberpunk-styled internet speed test & network diagnostics toolkit in Rust β as a terminal app, a desktop app, and an embeddable library.
β netrunner-core β the engine β no UI, embeddable
β speed test ββββ¬βββΆ netrunner_cli (Ratatui TUI)
β diagnostics β ββββΆ netrunner (Zed GPUI desktop app)
β history β
ββββββββββββββββββ
All network logic lives in one framework-free core crate; both front-ends subscribe to the same progress-event stream, so behaviour is identical across the terminal and the desktop.
| Speed test | Statistics dashboard | History |
|---|---|---|
![]() |
![]() |
![]() |
cargo install netrunner_cli # terminal app β `netrunner_cli`
cargo install netrunner # desktop app β `netrunner`
cargo add netrunner-core # embed the engine in your own projectnetrunner_cli # interactive menu
netrunner_cli -m speed # run a speed test
netrunner_cli -m diag # network diagnostics
netrunner_cli -m full # speed test + diagnostics
netrunner_cli --history # statistics dashboard (pie charts)
netrunner_cli --json # machine-readable output (no TUI)| Flag | Description | Default |
|---|---|---|
-m, --mode |
speed, diag, history, full, servers |
speed |
-s, --server |
Custom test server URL | auto |
-t, --timeout |
Per-test timeout (seconds) | 30 |
-d, --detail |
basic, standard, detailed, debug |
standard |
-j, --json |
JSON output, skip the TUI | off |
-n, --no-animation |
Disable animations | off |
Live download/upload bandwidth graphs render while the test runs, followed by a
results panel and β with --history β a full-screen dashboard of pie charts.
A Zed GPUI desktop app that runs the same engine and draws live download/upload bar charts as the test progresses, plus a summary of ping, throughput, connection quality, location, ISP and server.
cargo run -p netrunner # from a clone
netrunner # after `cargo install netrunner`The GUI needs a GPUI-capable platform (macOS, or Linux with the usual Vulkan/Wayland/X11 libraries). The core engine and TUI are fully headless.
Framework-free engine with no UI dependencies. Drop it into any async Rust project to measure connections, run diagnostics, or persist history.
use netrunner_core::{SpeedTest, TestConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let test = SpeedTest::new(TestConfig::default())?;
let r = test.run_full_test().await?;
println!("β {:.1} Mbps β {:.1} Mbps ping {:.0} ms [{}]",
r.download_mbps, r.upload_mbps, r.ping_ms, r.quality);
Ok(())
}The engine is UI-agnostic: pass a Tokio channel and it emits
[TestEvent]s (location, server selection, download/upload samples, latency,
completion) that you render however you like.
use netrunner_core::{SpeedTest, TestConfig, TestEvent};
use tokio::sync::mpsc;
let (tx, mut rx) = mpsc::unbounded_channel::<TestEvent>();
let test = SpeedTest::with_events(TestConfig::default(), Some(tx))?;
tokio::spawn(async move { let _ = test.run_full_test().await; });
while let Some(event) = rx.recv().await {
if let TestEvent::DownloadSample { mbps, .. } = event {
println!("download: {mbps:.1} Mbps");
}
}use netrunner_core::{HistoryStorage, NetworkDiagnosticsTool, TestConfig};
// Gateway, DNS, route, IPv6, interface
let diag = NetworkDiagnosticsTool::new(TestConfig::default())
.run_diagnostics().await?;
// Embedded redb store with rolling statistics
let store = HistoryStorage::new()?;
store.save_result(&result)?;
let stats = store.get_statistics()?;Public surface: SpeedTest, TestConfig, TestEvent, NetworkDiagnosticsTool,
HistoryStorage, SpeedTestResult, ConnectionQuality, and more β see
docs.rs/netrunner-core.
- Throughput β measured against Cloudflare's anycast speed backend
(
speed.cloudflare.com) so every one of the ~50 parallel connections actually transfers data; uses a lock-free counter, excludes the TCP slow-start warmup, and reports a trimmed sustained rate (comparable to speedtest.net). Supports gigabit+; a genuine failure reports 0 rather than a misleading floor. - Server selection β IP geolocation (5 providers with failover) β dynamic server discovery β Haversine distance + latency scoring β best server, used for latency/ping.
- Diagnostics β gateway, DNS servers & response time, route hops, IPv6, interface.
- History β embedded redb database with 30-day retention and per-run statistics.
Both apps share the same files under your config dir (~/.config/netrunner/ on
Linux, ~/Library/Application Support/netrunner/ on macOS):
| File | Format | What |
|---|---|---|
netrunner_history.db |
redb (binary) | speed-test history β shared by the TUI and GUI so past runs show up in both |
settings.json |
JSON | user preferences (default server, timeouts, auto_run, max_history, β¦) β human-editable |
The desktop app lists recent runs with download/upload trend charts, has an
editable Settings panel (server preset, test size, timeout, detail level)
that writes straight to settings.json, an Auto-run toggle, and a Clear
history button. History is a proper time-series in redb; JSON is reserved for
small, editable settings. You can still export history to JSON via
HistoryStorage::export_to_json.
This is a Cargo workspace driven by a justfile:
just build # build everything
just run-tui # run the terminal app
just run-gui # run the desktop app
just test # full workspace test suite
just test-headless # core + CLI only (no GPUI, mirrors CI)
just release 1.2.3 # gate β bump β tag β push β publish (via CI)| Crate | Package | Kind |
|---|---|---|
crates/netrunner-core |
netrunner-core |
library (embeddable engine) |
crates/netrunner-cli |
netrunner_cli |
binary (Ratatui TUI) |
crates/netrunner-gui |
netrunner |
binary (Zed GPUI desktop) |
MIT Β© Sorin Albu-Irimies β see LICENSE.


