NetLine is a Hammerspoon Spoon that displays a colored status line at the top of your screen(s) indicating network reachability status. It provides visual feedback on your network connectivity without requiring constant attention to a menubar icon.
- Visual Network Status: Shows a colored line at the top of your screen that indicates network status
- Multi-screen Support: Display on all screens, main screen only, or specific screens
- Customizable Appearance: Configure colors, height, position, and shadow effects
- Sound Alerts: Optional audio notifications for status changes
- Focus Mode Integration: Can respect Do Not Disturb/Focus modes for sound alerts
- Automatic Fading: Configure status line to automatically fade after specified duration
hs.loadSpoon("SpoonInstall")
spoon.SpoonInstall:andUse("NetLine")- Download the NetLine.spoon zip file from GitHub
- Unzip the file
- Double-click the NetLine.spoon file to install it to your Hammerspoon Spoons directory
Add this to your init.lua file:
hs.loadSpoon("NetLine")
spoon.NetLine:start()NetLine can be configured through Hammerspoon's settings system. Here's a full example with all available options:
-- Load NetLine
hs.loadSpoon("NetLine")
-- Configure (Optional - these are all default values)
hs.settings.set("NetLine.targetHost", "1.1.1.1")
hs.settings.set("NetLine.screen", "all") -- "all", "main", or part of screen name/UUID
hs.settings.set("NetLine.barHeight", 3) -- Height in pixels
hs.settings.set("NetLine.barYOffset", 0) -- Distance from top of screen
hs.settings.set("NetLine.horizontalPadding", 0) -- Padding on left/right edges
hs.settings.set("NetLine.shadowSize", 3) -- Shadow blur radius
hs.settings.set("NetLine.shadowOffsetY", -2) -- Shadow vertical offset
hs.settings.set("NetLine.shadowColorAlpha", 0.8) -- Shadow transparency (0.0-1.0)
hs.settings.set("NetLine.fadeDuration", 0.5) -- Animation duration in seconds
-- Status colors (can be any hs.drawing.color format)
hs.settings.set("NetLine.colors.reachable", hs.drawing.color.definedCollections.hammerspoon.osx_green)
hs.settings.set("NetLine.colors.unreachable", hs.drawing.color.definedCollections.hammerspoon.osx_red)
hs.settings.set("NetLine.colors.unknown", hs.drawing.color.definedCollections.hammerspoon.osx_yellow)
-- How long to show the bar before fading (0 = stay visible)
hs.settings.set("NetLine.fadeSeconds.reachable", 5.0)
hs.settings.set("NetLine.fadeSeconds.unreachable", 0.0) -- Stay visible when unreachable
hs.settings.set("NetLine.fadeSeconds.unknown", 3.0)
-- Sound alerts
hs.settings.set("NetLine.sounds.enabled", false)
hs.settings.set("NetLine.sounds.reachable", "Glass") -- System sound name or file path
hs.settings.set("NetLine.sounds.unreachable", "Basso") -- System sound name or file path
hs.settings.set("NetLine.sounds.unknown", "") -- Empty string for no sound
hs.settings.set("NetLine.sounds.volume", 0.7) -- 0.0 to 1.0
-- Logging level: "verbose", "debug", "info", "warning", "error"
hs.settings.set("NetLine.logLevel", "info")
-- Start NetLine
spoon.NetLine:start()targetHost: IP address or hostname to monitor for reachability (default: "1.1.1.1")
screen: Which screen(s) to display the status line on:"all": Display on all screens"main": Display only on the primary screen"partial name": Display on screens whose name or UUID contains this string
barHeight: Height of the status line in pixels (default: 3)barYOffset: Distance from the top edge of the screen (default: 0)horizontalPadding: Distance from left/right screen edges (default: 0)shadowSize: Size of the shadow effect (default: 3, 0 disables shadow)shadowOffsetY: Vertical offset of the shadow (default: -2)shadowColorAlpha: Transparency of the shadow (default: 0.8)fadeDuration: Animation duration when showing/hiding the bar (default: 0.5)
colors.reachable: Color when network is reachable (default: macOS green)colors.unreachable: Color when network is unreachable (default: macOS red)colors.unknown: Color when network status is unknown (default: macOS yellow)
fadeSeconds.reachable: How long to display the bar when network becomes reachable (default: 5.0 seconds)fadeSeconds.unreachable: How long to display the bar when network becomes unreachable (default: 0.0 - stay visible)fadeSeconds.unknown: How long to display the bar when network status is unknown (default: 3.0 seconds)
sounds.enabled: Master switch for sound notifications (default: false)sounds.reachable: Sound to play when network becomes reachable (default: "")sounds.unreachable: Sound to play when network becomes unreachable (default: "")sounds.unknown: Sound to play when network status is unknown (default: "")sounds.volume: Volume level for sound alerts (default: 0.7)
logLevel: Detail level for logs: "verbose", "debug", "info", "warning", "error" (default: "info")
NetLine provides the following methods:
Starts the network monitoring and displays the status line.
spoon.NetLine:start()Stops monitoring and removes the status line.
spoon.NetLine:stop()Returns a table with information about the current status.
local status = spoon.NetLine:status()
hs.inspect(status)The status table includes:
running: Boolean indicating if NetLine is activelastDisplayedStatus: Most recent status ("reachable", "unreachable", "unknown")targetHost: Current host being monitoredwatcherActive: Whether the reachability watcher is activecurrentReachabilityFlags: Current network flagsactiveCanvases: Information about displayed status lines
hs.loadSpoon("NetLine")
spoon.NetLine:start()hs.loadSpoon("NetLine")
hs.settings.set("NetLine.screen", "all")
hs.settings.set("NetLine.colors.reachable", {green=0.4, blue=0.9, alpha=0.7})
hs.settings.set("NetLine.colors.unreachable", {red=0.9, alpha=0.9})
spoon.NetLine:start()hs.loadSpoon("NetLine")
hs.settings.set("NetLine.sounds.enabled", true)
hs.settings.set("NetLine.sounds.reachable", "Glass")
hs.settings.set("NetLine.sounds.unreachable", "Basso")
hs.settings.set("NetLine.sounds.volume", 0.5)
spoon.NetLine:start()hs.loadSpoon("NetLine")
hs.settings.set("NetLine.barHeight", 5)
hs.settings.set("NetLine.shadowSize", 8)
hs.settings.set("NetLine.shadowOffsetY", -4)
hs.settings.set("NetLine.horizontalPadding", 100) -- Inset from edges
spoon.NetLine:start()NetLine requires the following Hammerspoon modules:
hs.canvashs.drawing.colorhs.loggerhs.networkhs.screenhs.settingshs.soundhs.fnutilshs.timerhs.inspect
The hs.focus module is used if available (for DND detection) but is optional.
https://github.com/FuzzyIdeas/IsThereNet For the idea and implementation details, this is more or less a port of that into hammerspoon.
- Check that Hammerspoon has accessibility permissions in System Preferences
- Try increasing the
barHeightsetting - Check your log console for errors (Console.app, filter for "Hammerspoon")
- Try changing the
targetHostto a reliable server (like "1.1.1.1" or "8.8.8.8") - Restart Hammerspoon
- Verify that
sounds.enabledis set totrue - Check that the sound names are valid system sounds
- Make sure your system volume is not muted
NetLine is released under the MIT License.
- Added multi-screen support
- Added sound alerts
- Added customizable shadow effects
- Added Focus Mode (DND) detection for sounds
- Improved error handling and logging
- Initial release
Contributions are welcome! Please feel free to submit a Pull Request on the GitHub repository.