speedcheck-js
v1.0.0
Published
A modern, full-featured internet speed test & network diagnostics library — download, upload, ping, IP info, location, ISP, network zone and more.
Maintainers
Readme
A modern, full-featured CommonJS package for internet speed testing and network diagnostics.
Measure download, upload, ping, latency, jitter — and get your public IP, geo-location, ISP, ASN, and network zone classification, all in one call.
✨ Features
| Feature | Details |
|---|---|
| ⬇️ Download Speed | Streams from CDN endpoints (Cloudflare, OVH, Hetzner) with auto-fallback |
| ⬆️ Upload Speed | POSTs binary payloads to discard endpoints, measures real throughput |
| 📡 Ping / Latency | Multi-target HTTP RTT with min / max / avg / median / jitter |
| 🌐 IP Address | Public IPv4 detection via multiple providers with fallback |
| 📍 Geo-Location | City, region, country, coordinates, timezone, postal code |
| 🏢 ISP & ASN | Internet Service Provider name, organisation, and ASN number |
| 🗺️ Network Zone | Classifies connection as residential / mobile / datacenter / VPN |
| 🔒 Privacy Detection | Detects VPN, proxy, Tor, and anonymisation services |
| 📱 Mobile Detection | Identifies cellular / LTE / 5G connections |
| 🎨 Pretty Output | Coloured terminal output with ASCII speed bars |
| 🔄 Auto-Fallback | Every module tries multiple providers — never a single point of failure |
| 📦 Zero native deps | Pure Node.js https for core logic; optional chalk / ora for CLI |
📦 Installation
# npm
npm install speedcheck-js
# yarn
yarn add speedcheck-js
# pnpm
pnpm add speedcheck-jsRequires Node.js ≥ 14
🚀 Quick Start
Run as CLI
node node_modules/speedcheck-js/src/index.jsOr add to your package.json scripts and run npm start.
Programmatic — full test
const { SpeedCheck, formatResults } = require('speedcheck-js');
(async () => {
const checker = new SpeedCheck();
const results = await checker.runAll();
console.log(formatResults(results));
// or use the raw object:
console.log(results);
})();📖 API Reference
new SpeedCheck(options?)
Main class that orchestrates all diagnostics.
const checker = new SpeedCheck({
pingRounds: 5, // number of ping samples (default: 5)
downloadDuration: 8000, // download test duration in ms (default: 8000)
uploadDuration: 6000, // upload test duration in ms (default: 6000)
verbose: false, // print live progress to stdout (default: false)
});Methods
| Method | Returns | Description |
|---|---|---|
| checker.runAll() | Promise<SpeedCheckResult> | Run all tests in parallel and return unified result |
| checker.checkIP() | Promise<IPInfo> | IP address + geo-location only |
| checker.checkPing() | Promise<PingResult> | Ping / latency only |
| checker.checkDownload() | Promise<SpeedResult> | Download speed only |
| checker.checkUpload() | Promise<SpeedResult> | Upload speed only |
| checker.classifyZone(ipInfo) | object | Classify network zone from an IPInfo object |
Individual modules
const {
getIPInfo, // IP + geo-location lookup
measurePing, // Ping / latency measurement
measureDownload, // Download speed measurement
measureUpload, // Upload speed measurement
getNetworkZone, // Network zone classification
formatResults, // Pretty-print a result object
} = require('speedcheck-js');getIPInfo()
const info = await getIPInfo();
// {
// ip: '203.0.113.42',
// city: 'Dhaka',
// region: 'Dhaka Division',
// country: 'Bangladesh',
// countryCode: 'BD',
// lat: 23.7104,
// lon: 90.4074,
// timezone: 'Asia/Dhaka',
// postalCode: '1000',
// isp: 'Grameenphone Ltd.',
// org: 'AS24389 Grameenphone Ltd.',
// asn: 'AS24389',
// isProxy: false,
// isMobile: false,
// provider: 'ipapi.co'
// }measurePing(rounds?)
const ping = await measurePing(5);
// {
// min: 12,
// max: 48,
// avg: 24,
// median: 22,
// jitter: 6,
// samples: [12, 18, 22, 30, 48],
// unit: 'ms'
// }measureDownload(durationMs?, verbose?)
const dl = await measureDownload(8000);
// {
// mbps: 94.32,
// kbps: 94320,
// MBs: 11.79,
// bytesReceived: 94320000,
// elapsedMs: 8012,
// source: 'Cloudflare 25MB',
// unit: 'Mbps'
// }measureUpload(durationMs?, verbose?)
const ul = await measureUpload(6000);
// {
// mbps: 42.10,
// kbps: 42100,
// MBs: 5.26,
// bytesSent: 31575000,
// elapsedMs: 6003,
// source: 'Cloudflare',
// unit: 'Mbps'
// }getNetworkZone(ipInfo)
const zone = getNetworkZone(ipInfo);
// {
// type: 'residential', // 'residential' | 'mobile' | 'datacenter' | 'vpn'
// privacy: 'standard', // 'standard' | 'high' | 'low'
// hosting: false,
// mobile: false,
// vpn: false,
// description: 'Standard home or office internet connection'
// }SpeedCheckResult shape
{
startedAt: '2026-04-30T10:00:00.000Z',
finishedAt: '2026-04-30T10:00:22.000Z',
ip: '203.0.113.42',
location: {
city, region, country, countryCode,
lat, lon, timezone, postalCode
},
isp: 'Grameenphone Ltd.',
org: 'AS24389 Grameenphone Ltd.',
asn: 'AS24389',
networkZone: { type, privacy, hosting, mobile, vpn, description },
ping: { min, max, avg, median, jitter, samples, unit },
download: { mbps, kbps, MBs, bytesReceived, elapsedMs, source, unit },
upload: { mbps, kbps, MBs, bytesSent, elapsedMs, source, unit },
errors: { ip, ping, download, upload } // null if no error
}🧪 Running Tests
node test.jsThe test suite covers:
- Unit tests (no network required) — formatters, zone classifier, constructor defaults
- Integration tests (network required) — IP lookup, ping, download, upload, full
runAll()
📁 Project Structure
speedcheck/
├── src/
│ ├── index.js ← Entry point & CLI runner
│ ├── speedcheck.js ← Main SpeedCheck class
│ ├── ipinfo.js ← IP & geo-location lookup
│ ├── ping.js ← Ping / latency measurement
│ ├── download.js ← Download speed measurement
│ ├── upload.js ← Upload speed measurement
│ ├── zone.js ← Network zone classification
│ └── formatter.js ← Terminal output formatter
├── test.js ← Full test suite
├── package.json
└── README.md🔧 How It Works
speedcheck.runAll()
│
├─► getIPInfo() → tries ipapi.co → ipwho.is → ipify.org
│
├─► measurePing() → HTTP HEAD to Google, Cloudflare, Amazon, Microsoft, Apple
│
├─► measureDownload() → streams from Cloudflare → OVH → Hetzner
│
└─► measureUpload() → POST to Cloudflare → httpbin
│
└─► getNetworkZone(ipInfo) → classifies connection typeAll four run in parallel via Promise.allSettled — a failure in one never blocks the others.
🌍 Provider Fallback Chain
| Module | Primary | Fallback 1 | Fallback 2 | |---|---|---|---| | IP Info | ipapi.co | ipwho.is | ipify.org | | Download | Cloudflare | OVH | Hetzner | | Upload | Cloudflare | httpbin | — | | Ping | google.com | cloudflare.com | amazon.com + more |
📄 License
Made with ❤️ by Sheikh Tamim
