@ghuts/speedtest
v1.0.0
Published
Fast & accurate modular network speed test — download, upload, latency, jitter, packet loss, ISP info
Downloads
103
Maintainers
Readme
⚡ @ghuts/speedtest
Fast & accurate modular network speed test for Node.js. Zero dependencies.
Measures download speed, upload speed, latency, jitter, packet loss, ISP info, and server location — similar to speed.cloudflare.com and speedtest.net.
Features
- 🚀 Adaptive multi-stream — parallel connections with progressive chunk sizes
- 📊 Statistically accurate — median, percentiles, IQR outlier removal
- 🏓 Latency & Jitter — 20-round ping test with warmup
- 📦 Packet Loss — 30-probe estimation
- 🌐 ISP & Location — IP, provider, city, country, coordinates, ASN
- 🔒 Connection info — HTTP protocol, TLS version, Cloudflare colo
- 🧩 Fully modular — import individual modules or run the full suite
- 📦 Zero dependencies — uses only Node.js built-in
fetch - ⏱️ ~30s full test — 12s cap per download/upload phase
Install
npm install @ghuts/speedtestOr run directly:
npx @ghuts/speedtestCLI Usage
# Full test
npx @ghuts/speedtest
# JSON output
npx @ghuts/speedtest --json
# Individual tests
npx @ghuts/speedtest --download
npx @ghuts/speedtest --upload
npx @ghuts/speedtest --latency
npx @ghuts/speedtest --info
npx @ghuts/speedtest --packetlossProgrammatic Usage
import { runSpeedTest } from '@ghuts/speedtest';
const results = await runSpeedTest();
console.log(results.download.speed); // Mbps (median)
console.log(results.upload.speed); // Mbps (median)
console.log(results.latency.median); // ms
console.log(results.latency.jitter); // ms
console.log(results.network.client.isp);Custom Configuration
const results = await runSpeedTest({
download: true,
upload: true,
latency: true,
packetLoss: true,
networkInfo: true,
maxDownloadDurationMs: 12000,
maxUploadDurationMs: 12000,
latencyRounds: 20,
packetLossRounds: 30,
onProgress: (info) => {
console.log(info.phase, info);
},
});Individual Modules
import { measureDownload } from '@ghuts/speedtest/download';
import { measureUpload } from '@ghuts/speedtest/upload';
import { measureLatency } from '@ghuts/speedtest/latency';
import { getNetworkInfo } from '@ghuts/speedtest/serverinfo';
import { measurePacketLoss } from '@ghuts/speedtest/packetloss';
const download = await measureDownload({ maxDurationMs: 10000 });
const upload = await measureUpload({ maxDurationMs: 10000 });
const latency = await measureLatency({ rounds: 15 });
const info = await getNetworkInfo();
const loss = await measurePacketLoss({ rounds: 20 });Output Example
╔════════════════════════════════════════════════════════╗
║ ⚡ SPEED TEST RESULTS ║
╚════════════════════════════════════════════════════════╝
┌────────────────────────────────────────────────────────┐
│ 🌐 NETWORK INFO │
├────────────────────────────────────────────────────────┤
│ IP Address: 203.0.113.42 │
│ ISP: AS12345 Example Telecom │
│ City: Jakarta │
│ Country: ID │
│ Server: CGK │
│ Protocol: http/2 │
│ TLS: TLSv1.3 │
└────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────┐
│ 🏓 LATENCY & JITTER │
├────────────────────────────────────────────────────────┤
│ Ping (median): 12.45 ms │
│ Jitter: 2.31 ms │
└────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────┐
│ ⬇️ DOWNLOAD SPEED │
├────────────────────────────────────────────────────────┤
│ Speed (median): 85.42 Mbps │
└────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────┐
│ ⬆️ UPLOAD SPEED │
├────────────────────────────────────────────────────────┤
│ Speed (median): 42.18 Mbps │
└────────────────────────────────────────────────────────┘Result Object Structure
{
network: {
client: { ip, isp, asn, city, region, country, latitude, longitude, timezone, postal },
server: { name, location, ip },
connection: { type, httpProtocol, tlsVersion, gateway }
},
latency: {
min, max, avg, median, p90, p95, p99, jitter, samples
},
download: {
speed, avg, max, min, p10, p90, p95, totalBytes, totalDurationMs, samples
},
upload: {
speed, avg, max, min, p10, p90, p95, totalBytes, totalDurationMs, samples
},
packetLoss: {
sent, received, lost, timedOut, errors, lossPercent
},
meta: {
timestamp, totalDurationMs, version
}
}How It Works
- Network Info — Queries Cloudflare meta API, ipinfo.io, and CF trace in parallel
- Latency — 3 warmup pings + 20 measured pings to
speed.cloudflare.com, IQR outlier removal - Download — 5 adaptive phases (10KB → 25MB), 1–8 parallel streams, measures throughput
- Upload — Same adaptive strategy with pre-generated payloads
- Packet Loss — 30 HTTP HEAD probes in batches of 5
All measurements use median as the primary metric (more robust than average) with IQR-based outlier removal for accuracy.
Requirements
- Node.js >= 18.0.0 (for built-in
fetchandAbortSignal.timeout)
License
MIT
