{"id":51401471,"url":"https://github.com/tarunvishwakarma1/netspd","last_synced_at":"2026-07-04T07:01:18.730Z","repository":{"id":369115332,"uuid":"1288435257","full_name":"TarunVishwakarma1/netspd","owner":"TarunVishwakarma1","description":"Network Speed test made easy","archived":false,"fork":false,"pushed_at":"2026-07-03T17:21:02.000Z","size":4045,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-03T18:17:39.824Z","etag":null,"topics":["network","ratatui","rust","speedtest","terminal","tui"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TarunVishwakarma1.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-03T15:43:59.000Z","updated_at":"2026-07-03T17:26:10.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/TarunVishwakarma1/netspd","commit_stats":null,"previous_names":["tarunvishwakarma1/netspd"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/TarunVishwakarma1/netspd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TarunVishwakarma1%2Fnetspd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TarunVishwakarma1%2Fnetspd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TarunVishwakarma1%2Fnetspd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TarunVishwakarma1%2Fnetspd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TarunVishwakarma1","download_url":"https://codeload.github.com/TarunVishwakarma1/netspd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TarunVishwakarma1%2Fnetspd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35112708,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-04T02:00:05.987Z","response_time":113,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["network","ratatui","rust","speedtest","terminal","tui"],"created_at":"2026-07-04T07:01:18.094Z","updated_at":"2026-07-04T07:01:18.718Z","avatar_url":"https://github.com/TarunVishwakarma1.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# netspd\n\n**A beautiful, modern network speed test for your terminal — with a hypercar tachometer.**\n\n[![CI](https://github.com/TarunVishwakarma1/netspd/actions/workflows/ci.yml/badge.svg)](https://github.com/TarunVishwakarma1/netspd/actions/workflows/ci.yml)\n[![Crates.io](https://img.shields.io/crates/v/netspd.svg)](https://crates.io/crates/netspd)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![Rust](https://img.shields.io/badge/rust-1.88%2B-orange.svg)](Cargo.toml)\n\n\u003cimg src=\"https://raw.githubusercontent.com/TarunVishwakarma1/netspd/main/assets/recording.gif\" alt=\"netspd running a speed test with an animated tachometer dial\" width=\"800\"\u003e\n\n\u003c/div\u003e\n\nnetspd measures **ping, jitter, download and upload** against LibreSpeed-compatible servers and renders them live on a braille-canvas instrument cluster: a spring-loaded needle with an ignition sweep, a heat-gradient band that reddens toward the hatched redline, a session-peak ghost notch, and a latency sub-dial — in the spirit of tools like `btop`, `gitui` and `lazygit`.\n\n## Features\n\n- **Hypercar tachometer** — heat-gradient value band, hatched redline, spring-physics needle with afterglow, ignition sweep before each phase, peak ghost notch, latency sub-dial; twin instrument cluster on wide terminals\n- **Live metrics** — current / average / peak speed, transferred bytes, ETA, elapsed time\n- **Latency analysis** — multiple samples, outlier trimming, jitter, real ICMP packet loss (graceful fallback where ICMP is unavailable)\n- **Smart server discovery** — health-probes the public server list, drops dead servers, auto-selects the nearest\n- **Headless mode** — `--no-tui` for scripts and cron, `--json` for machine-readable reports\n- **Result history** — every run appended as JSON lines to your data directory\n- **Streaming transfers** — nothing buffered in memory; parallel connections with EMA smoothing\n- **Themes** — Default, Nord, Dracula, Catppuccin, Gruvbox, plus your own TOML themes without recompiling\n- **Responsive layout** — adapts from 80×24 up to 4K terminals\n- **Graceful everywhere** — cancellation, retries, timeouts; network failures never panic\n\n## Installation\n\n### Cargo\n\n```sh\ncargo install netspd\n```\n\nCompiles from [crates.io](https://crates.io/crates/netspd); requires Rust 1.88 or newer.\n\n### Homebrew (macOS / Linux)\n\n```sh\nbrew tap TarunVishwakarma1/tap\nbrew install netspd\n```\n\n### Prebuilt binaries\n\nDownload the archive for your platform from the [latest release](https://github.com/TarunVishwakarma1/netspd/releases/latest), unpack it and put `netspd` on your `PATH`.\n\n### From source\n\n```sh\ngit clone https://github.com/TarunVishwakarma1/netspd\ncd netspd\ncargo install --path .\n```\n\nRequires Rust 1.88 or newer.\n\n## Usage\n\n```sh\nnetspd                     # full TUI\nnetspd --no-tui            # headless: progress on stderr, summary on stdout\nnetspd --json              # headless: report as one JSON object on stdout\nnetspd --list-servers      # print reachable servers, nearest first\nnetspd -s tokyo            # pick a server by name/host substring\nnetspd -d 5 -c 8           # 5-second phases over 8 connections\n```\n\nThe test starts automatically: ping → download → upload, then a results summary. If a server fails mid-test, netspd automatically retries with the next-nearest one (unless you pinned a server with `--server`).\n\n### Keyboard\n\n| Key | Action |\n| --- | --- |\n| `q` / `Esc` | Quit (Esc closes overlays first) |\n| `r` | Restart the test |\n| `g` | Result trends from your history |\n| `s` | Server selection |\n| `t` | Theme selector |\n| `c` | View configuration |\n| `?` | Help |\n| `↑↓` / `jk`, `Enter` | Navigate and confirm in lists |\n\n### Scripting\n\n`--json` prints exactly one JSON object on stdout and nothing else, so it pipes cleanly:\n\n```sh\nnetspd --json | jq .download_mbps\n```\n\n```json\n{\n  \"timestamp\": 1783092092,\n  \"server\": \"Tokyo, Japan (A573)\",\n  \"ping_ms\": 141.2,\n  \"jitter_ms\": 1.0,\n  \"packet_loss_pct\": 0.0,\n  \"download_mbps\": 93.7,\n  \"download_peak_mbps\": 171.0,\n  \"download_bytes\": 117193129,\n  \"upload_mbps\": 66.3,\n  \"upload_peak_mbps\": 87.8,\n  \"upload_bytes\": 82837504\n}\n```\n\nExit code is `0` on a completed test and `1` on any failure. Every completed run (TUI or headless) is also appended to `\u003cdata dir\u003e/netspd/history.jsonl` (macOS: `~/Library/Application Support/netspd/`, Linux: `~/.local/share/netspd/`), one JSON object per line.\n\n## Configuration\n\nnetspd reads the first `config.toml` found in:\n\n1. `$XDG_CONFIG_HOME/netspd/config.toml` (macOS: `~/Library/Application Support/netspd/config.toml`)\n2. `./config/config.toml`\n\nEvery key is optional; see [`config/config.toml`](config/config.toml) for the annotated reference. Highlights:\n\n```toml\ntheme = \"catppuccin\"       # default | nord | dracula | catppuccin | gruvbox\nrefresh_rate = 30          # UI frames per second (1..=60)\nprovider = \"librespeed\"\nanimation_speed = 1.0\n\n[engine]\nduration_secs = 10         # length of each transfer phase\nconnections = 4            # parallel connections\nping_samples = 10\n\n[[servers]]                # optional: pin your own backend\nname = \"My Server\"\nurl = \"https://speedtest.example.com/backend/\"\n```\n\nCustom themes go in `~/.config/netspd/themes/*.toml` — copy any file from [`assets/themes/`](assets/themes) as a starting point.\n\n## Architecture\n\nnetspd follows clean architecture with strict one-way dependencies:\n\n```\n┌──────────────────────────────────────────────┐\n│ tui/          presentation (Ratatui only)    │\n│   theme · animation · widgets · screens      │\n├──────────────────────────────────────────────┤\n│ app/          application                    │\n│   events → controller → state → renderer    │\n├──────────────────────────────────────────────┤\n│ engine/       domain (no UI imports)         │\n│   Engine → scheduler → providers/network     │\n│   metrics: EMA · sampler · throughput ·      │\n│            latency · statistics              │\n├──────────────────────────────────────────────┤\n│ config/ · errors/ · utils/   infrastructure  │\n└──────────────────────────────────────────────┘\n```\n\n- The **engine** emits strongly-typed `EngineEvent`s over a channel and never imports Ratatui — it is directly reusable from a CLI, GUI, REST API or as a library.\n- **Providers** implement one trait (`Provider`); adding a new speed test network touches nothing else.\n- **State** is plain data mutated only by reducers; the renderer just draws it.\n- **Metrics** are pure, deterministic calculators, each independently unit-tested.\n\n## Development\n\n```sh\ncargo test            # unit + integration tests\ncargo clippy          # lint-clean, unwrap/expect/panic denied\ncargo fmt --check\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the layering rules and PR checklist.\n\n## Roadmap\n\n- [x] JSON result export and `--no-tui` CLI mode\n- [x] Result history (JSON lines)\n- [x] Trend sparklines over the stored history (`g`)\n- [x] `--server`, `--list-servers`, `--duration`, `--connections` flags\n- [x] Automatic failover to the next server on failure\n- [x] Packet loss via ICMP echo probing\n- [x] Homebrew tap\n- [ ] Ookla and Fast.com providers\n- [ ] Scheduled repeat testing\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftarunvishwakarma1%2Fnetspd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftarunvishwakarma1%2Fnetspd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftarunvishwakarma1%2Fnetspd/lists"}