Skip to content

Repository files navigation

Router Menu — signal, band and throughput, always one glance away

Router Menu

Keep an eye on your connection from the macOS menu bar — battery, signal, and how much data you've used, without opening a web panel. Works with ZTE 5G modems, ASUS routers, and an iPhone Personal Hotspot.

The icon shows up only while you're actually on that network, and stays out of the way the rest of the time.

Release License: MIT macOS 14+

How it looks

A regular router (ASUS) — network status, this Mac's address, and live transfer with a 24-hour chart:

The popover for an ASUS router — network status, this Mac's IP, and live transfer speeds with a 24-hour chart

A mobile modem (ZTE) — the same, plus signal quality, network type, and a battery with its own history:

The popover for a mobile ZTE modem — battery level, signal strength, network type, transfer speeds, and a battery history chart

An iPhone Personal Hotspot — the tether read from the Mac's own interface, with the link medium and traffic since the connection came up:

The popover for an iPhone Personal Hotspot — the link medium, this Mac's address on the tether, and traffic since the connection came up

Install

brew tap RadnoK/tap
brew install --cask router-menu

Or grab the .zip from Releases and drag Router Menu.app into /Applications.

The app is signed and notarized by Apple, so it opens without Gatekeeper warnings. It runs natively on both Apple Silicon and Intel Macs.

What you get

At a glance in the menu bar — the icon fills up as your signal gets stronger, so you can tell reception from across the room.

Click for the details:

  • Battery level, and whether the modem is charging
  • Signal strength and network type (5G, LTE, …)
  • Current up and down speed
  • Data used this month and in total
  • How long the connection has been up
  • Small charts of battery and data over the last 24 hours

Optional signal diagnostics — RSRP and SINR, two numbers the modem reports that tell you how clean the cellular signal is. Useful when you're hunting for the best spot to put the modem; easy to ignore otherwise. You can hide them, along with any other group of stats, in Settings.

Speaks your language — English and Polish. Follows your Mac's language, or you can pick one in Settings.

Requirements

  • macOS 14 or newer

  • One of:

    • A ZTE 5G modem with a web panel at 192.168.0.1 — developed against the ZTE U50, and likely to work with related models that share the same web panel.
    • An ASUS router running Asuswrt.
    • An iPhone (or Android) Personal Hotspot — no setup on the phone, the Mac reads its own end of the tether. Note that iOS does not share the phone's battery or cellular signal with a Mac, so those are not shown.

    If you try another device, let me know how it goes.

Setup

Most of it works the moment you install it. Two things are worth knowing.

Finding your modem

The app needs to know when you're on the modem's network, and there are two ways it can tell:

  • By Wi-Fi name — matches your network name. macOS only lets apps read the Wi-Fi name if you grant location permission, so you'll see that prompt on first launch. Nothing about your location is read, sent, or stored; it's just the gate macOS puts in front of the network name.
  • By modem address — checks whether the modem answers at its IP. No location permission needed.

Pick whichever you prefer in Settings, under General.

Data counters

Battery, signal, and current speed work right away.

The monthly and total counters are different: the modem only reports them to a logged-in session. Put your modem's web panel password into Settings under Account, and the counters start filling in. The password goes into your macOS keychain and is only ever sent to the modem on your own network.

Don't want to bother? Leave it empty. Everything else keeps working.

Updates

The app updates itself. You can turn that off, change how often it checks, or check right now — all under Updates in Settings. Updates are cryptographically signed and verified before anything is installed.

Privacy

The app talks to your modem and nothing else.

  • No analytics, no telemetry, no external servers — all traffic stays on your local network.
  • Your modem password lives in the macOS keychain.
  • The 24-hour history is a local file in ~/Library/Application Support/zte-menu/.
  • Location permission, if you grant it, is used for exactly one thing: reading your Wi-Fi network name. Your location is never read or transmitted.

Not seeing the icon?

If you use a menu bar manager like Bartender or Ice, it may have tucked the new icon into the hidden section. Check there and mark Router Menu as always visible.

Otherwise, remember the icon is hidden by design when you're not connected to the modem — that's usually the explanation.

Contributing

Bug reports and pull requests are welcome. If something's broken or your modem isn't supported, open an issue.

Building from source

You'll need a Swift 6 toolchain (ships with recent Xcode). There's no Xcode project — it's a Swift package.

swift test              # run the test suite (64 tests)
./scripts/build-app.sh  # build and package into a .app
open "dist/Router Menu.app"

build-app.sh produces a universal binary, assembles the app bundle, and ad-hoc signs it so it runs locally.

How it fits together

The code is layered so the interesting parts can be unit tested without a modem attached: parsing, formatting, state, and history are plain Swift with no system dependencies, while the pieces that touch the network, the keychain, and Core Location sit behind thin injected wrappers. SwiftUI views read from an observable store and stay free of business logic.

Talking to the modem was worked out by watching its own web panel: logging in hashes the password, and the resulting session cookie is replayed on later requests. ModemClient and ZTEAuth hold that logic, and the tests pin it against captured responses.

Releasing

Bump the version in Resources/Info.plist, then push a matching tag:

git tag v0.4.0 && git push origin main v0.4.0

GitHub Actions takes it from there — builds, signs, notarizes, publishes the release, updates the appcast, and bumps the Homebrew cask.

To cut a release from your own machine instead, run ./scripts/release.sh <version>. It picks up the Developer ID certificate from your keychain on its own; if you hold more than one, it stops and asks you to name the one to use:

SIGN_IDENTITY=<sha1-hash> ./scripts/release.sh 0.6.3

security find-identity -v -p codesigning lists the hashes.

License

MIT © Konrad Alfaro

About

Menu bar status for ZTE modems and ASUS routers

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages