Tool · Command line · Network diagnostics

NetCheck

macOS network diagnostics · Private tool

Production

All projects

NetCheck browser report for a healthy connection through a travel router running a VPN: Online, Protected — Router VPN and Healthy tiles, a diagnosis line, six cards of measurements, and a network path from the Mac to the VPN exit
01The story

Problem, approach, outcome

When a connection goes bad on the road, every failure looks the same: pages hang, the VPN app says “connected,” the router’s lights are green. My travel setup has a chain of links between the laptop and the Internet — Wi-Fi to a travel router, a USB tether to a phone, a roaming cellular carrier, a VPN tunnel back to the US — and any one of them can be the one failing. Speed tests and “is it down?” sites give one number for the whole chain, and a successful ping, the usual proof of “online,” is often the most confidently wrong answer on the screen.

Test each layer on its own, and report only what was measured. Every run checks the network interface, the router, raw IP, DNS, TCP, TLS and the VPN exit in parallel, each with its own timeout, then names the lowest layer that failed — with what was observed kept apart from what might be causing it. The rule came from the bug that started the project: ping, DNS and TCP all passed, but the TLS handshake stalled. The cause was a VPN packet size too large for the tethered path. NetCheck now recognizes that signature and offers it as a lead, not a verdict.

Accuracy matters more than a green tick. The VPN exit is checked against a saved profile and the provider’s own verdict, so a dropped tunnel and a normal day never look alike. Packet loss needs a second witness, TCP retries, before it’s called heavy. A low download is measured again on its own before it’s reported, because inside a VPN tunnel the upload test can crowd it out. Hotel sign-in pages are detected before they can skew anything else. And the browser report knows its own age: after thirty minutes it stops claiming to know.

It’s a single shell script that relies only on tools macOS already ships with. A test harness runs the real script against 25 simulated networks — router VPN, VPN on the Mac, sign-in pages, the TLS stall, hotel Wi-Fi at 60% packet loss — on every push, and its thresholds are checked against real runs from hotels, apartment rentals and an in-flight satellite connection.

NetCheck is the first thing I run when a connection misbehaves, and its report is built to be screenshotted and read by someone else, often an AI assistant in the middle of troubleshooting. It has settled real questions: whether a slow video call was the hotel or the VPN, why an SFTP upload stalled while browsing worked, and why in-flight Wi-Fi crawled. On that flight, the same satellite link gave 68 Mbps without the VPN and under 1 Mbps through it.

02Overview

About NetCheck

NetCheck is a command-line network diagnostic for macOS. One command checks the Wi-Fi link, the router, each layer of the Internet path, the public exit and VPN status, and connection quality, then prints a single diagnosis: what’s working, the lowest layer that isn’t, and what to try next. netcheck --html writes the same results as a one-screen dashboard, and --json hands them to other scripts.

I built it for working while traveling, over a travel router, a phone tether and a VPN, where 300 ms of latency is normal and “the Internet is slow” can mean five different things. It began in September 2026 as a quick status check for that router and grew one field problem at a time: each version starts from a real failure, and each failure becomes a test case.

The principle behind it is simple: never report a conclusion that wasn’t measured. A tool that raises false alarms gets ignored, so NetCheck says “not checked” or “unknown” when that’s the honest answer, and never shows a green tick it didn’t earn.

03Features

What it does

  • Tests the interface, router, ping, DNS, TCP, TLS and HTTPS separately, in parallel, each with its own timeout
  • One diagnosis from the lowest layer that failed, with observations kept apart from possible causes
  • VPN exit checked against a saved profile and the provider’s own verdict, whether the VPN runs on the router or the Mac
  • Connection quality — Healthy, Usable or Degraded — from latency, loss and an optional speed test
  • Hotel and airport sign-in pages detected before they can skew the results
  • Network capability probe (which protocols a network lets out) and a read-only packet-size check for VPN problems
  • SSH and SFTP tested step by step, without logging in, and compared with the VPN on and off
  • A self-contained browser report that fits one screen and marks itself stale, plus JSON output for scripts
05Stack

How it’s built

  • One zsh script on macOS built-ins: curl, dig, ping, networkQuality
  • Python 3 for JSON and the report
  • Self-contained HTML report: inline CSS and SVG, works offline
  • Test harness: 25 simulated networks, no network needed
  • GitHub Actions on every push
  • Every change tracked in Linear, one ticket per commit
06Roadmap

Where it’s going

  1. Shipped

    Layered diagnosis

    Every layer tested on its own, with one honest finding from the lowest that failed.

  2. Shipped

    One-screen browser report

    A dashboard with a network path diagram, built to be shared, that knows when it’s out of date.

  3. Shipped

    SSH checks and speed rechecks

    Step-by-step SSH tests and a second measurement before a low speed is reported.

  4. Next

    Speed history

    Compare throughput with and without the VPN on the same network, as SSH runs already are.

  5. Next

    Satellite and accelerated networks

    Recognize networks that speed up TCP locally, and explain why a VPN is so much slower there.

  6. Exploring

    Menu bar status

    A glanceable indicator driven by the JSON output.

Have a problem a small, focused tool could solve?

This is the kind of work I do at 321 Enterprise. Tell me what slows your team down and we’ll see what we can build.

Start a conversation See all projects