Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NetSpeedBar

A small macOS menu bar app that shows live download and upload speed.

NetSpeedBar in the macOS menu bar, showing 10 KB/s down and 11 KB/s up

Live throughput, stacked two-line by default — download on top, upload below.

No Dock icon, no window — it lives entirely in the menu bar (LSUIElement). Pure AppKit, no third-party dependencies.

Download

Download NetSpeedBar 1.0.0 — universal binary, macOS 13 or later

Unzip, move it to /Applications, then clear the quarantine flag macOS attaches to downloads:

xattr -dr com.apple.quarantine /Applications/NetSpeedBar.app
open /Applications/NetSpeedBar.app

That step is not optional. The app is ad-hoc signed rather than notarized, so Gatekeeper refuses to open it and reports it as damaged. It is not damaged — the bundle passes codesign --verify --strict; the message is what macOS shows for any un-notarized app that arrived with a quarantine flag.

Building from source avoids this entirely, since a locally built copy is never quarantined.

Build & run

./build.sh
open dist/NetSpeedBar.app

build.sh produces a universal (arm64 + x86_64) release binary, wraps it in dist/NetSpeedBar.app, and ad-hoc signs it.

To install it properly:

cp -R dist/NetSpeedBar.app /Applications/

Launch at login can be toggled from the menu, or scripted — registration has to run from inside the app, and it registers whatever copy it is run from, so run the one in /Applications:

/Applications/NetSpeedBar.app/Contents/MacOS/NetSpeedBar --enable-login-item

--disable-login-item and --login-item-status are also accepted.

Menu

The NetSpeedBar menu open, showing Wi-Fi (en0), session totals, and the Display, Units and Update Every submenus

Click the readout to get:

  • The connections carrying traffic, by friendly name — e.g. Wi-Fi (en0). Ports that are up but idle (Thunderbolt bridges, empty Ethernet adapters) are filtered out, so this names the link in use rather than every port
  • Session totals, with a reset
  • Display — stacked (two lines) or single line
  • Units — bytes (MB/s) or bits (Mbps)
  • Update Every — 1, 2 or 5 seconds
  • Launch at Login
  • Open Activity Monitor / Quit

Settings persist in UserDefaults.

How it measures

Byte counters come from sysctl(NET_RT_IFLIST2), and speed is the delta between two samples divided by the real elapsed time.

Two details worth knowing:

  • NET_RT_IFLIST2, not getifaddrs. The getifaddrs counters are 32-bit and wrap every 4 GB — under a minute on a gigabit link. NET_RT_IFLIST2 carries the 64-bit if_data64 totals instead.

  • Physical interfaces only (en*, pdp_ip*, ppp*). VPN tunnels (utun*) are deliberately excluded: that traffic also crosses the physical interface, so counting both would double every byte. AirDrop-style peer-to-peer links (awdl*, llw*) are excluded as not-internet.

  • Deltas are per interface, then summed — never taken on a pre-summed total. An interface appearing mid-session (a dock plugged in, Wi-Fi switched back on) arrives carrying its whole lifetime counter; subtracting summed totals would report that as one enormous burst that never happened. An interface with no previous reading is skipped for that tick and baselined for the next.

Samples taken across a gap longer than 10 seconds are discarded rather than reported, so waking from sleep doesn't render as a huge spike.

App icon

The icon is drawn in code rather than checked in as an opaque binary, so it can be adjusted and re-rendered:

swift Tools/GenerateIcon.swift

That writes Resources/AppIcon.icns (every size from 16 to 1024, at 1x and 2x) plus build/icon-preview.png for eyeballing. build.sh regenerates it automatically if the .icns is missing, and copies it into the bundle.

Because this is a menu bar app with no Dock presence, the icon shows up in Finder, Get Info, and System Settings › General › Login Items.

Menu bar layout

The readout is drawn into a template image, not set as the status button's title. Fitting two lines into a title requires clamping the line height, and that clamping pins the block to the top of the bar rather than centring it — 1.5 pt of space above and 10.5 pt below, measured. AppKit centres an image on its own, and a template image is tinted by the system, so light/dark and the click highlight are handled for free.

Vertical ink, measured against the real 30 pt menu bar:

above below
title-based (before) 1.5 pt 10.5 pt
image-based (now) 7.5 pt 6.5 pt
a neighbouring system icon 7.0 pt 7.0 pt

Note that NSStatusBar.system.thickness reports 22 pt — that is the item thickness, not the bar. The bar itself is 30 pt here, from NSScreen.frame.maxY - visibleFrame.maxY.

Horizontal spacing

Two separate things control how much room the readout takes:

  1. The item's own width, sized to the text actually being drawn rather than to the widest string it could ever show.
  2. The padding AppKit reserves around it, trimmed via NSStatusItemSpacing / NSStatusItemSelectionPadding, written to this app's current-host preference domain at launch. This is not the system-wide setting — every other menu bar item keeps its normal spacing.

Measured from a screenshot (2x pixels, threshold on glyph brightness):

gap after the readout gap between two system icons
default spacing 21.0 pt 22.5 pt
trimmed 13.0 pt 22.5 pt

To go tighter still you would have to compress every item, which is a system-wide change and affects the whole menu bar:

defaults -currentHost write -globalDomain NSStatusItemSpacing -int 6

That one needs a log out and back in, and is reverted with defaults -currentHost delete -globalDomain NSStatusItemSpacing.

Verified against

netstat -ib

Reading the same interval both ways agrees: ~1.1 MB/s in the menu bar against 1015 KB/s of en0 bytes-in over the sampling window.

Notes

  • The signature is ad-hoc, which is fine on this Mac. Copying the app to another machine would need a Developer ID signature and notarization.
  • Launch at Login uses SMAppService, which needs a real app bundle — it will not work if you run the bare binary out of .build/.

See also

One of three small macOS menu-bar utilities, shown here running side by side:

All three utilities in the macOS menu bar

  • NetSpeedBar — live download and upload speed ← you are here
  • DisplayHelper — keeps the display awake and the system marked active
  • PowerToggleBar — one-click battery saver with exact restore

License

MIT — see LICENSE.

About

macOS menu bar app showing live download and upload speed. Pure AppKit, no dependencies.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages