CLI tool
tonsky/AnyBar avatar
tonsky/AnyBar

AnyBar: a menubar dot driven by a UDP port

OS X menubar status indicator

6,041 stars158 forksObjective-CEPL-1.0

At a glance

What is it?
AnyBar is a macOS menubar indicator that displays one colored dot and accepts commands over UDP. It suits developers who want a build or job status light they can wire into any script, and it is the wrong tool for anyone who needs history, alerts or a cross-platform tray.
Who is it for?
Adopt AnyBar if you want a single status dot on macOS that any script, language or CI step can drive with one UDP datagram, and if you accept that the dot carries no history, no labels beyond an optional title, and no alerting. Do not adopt it if you need a Windows or Linux tray, a queryable status API, or a widget that survives a crash with state intact.
Can I use it commercially?
Yes, with conditions. EPL-1.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Objective-C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What problem AnyBar solves, and for whom

Long-running commands on a laptop are invisible. A test suite, a compile, a deploy script or a batch job runs in a terminal tab you are not looking at, and you find out it finished only when you switch back. AnyBar reduces that to a single colored dot in the macOS menubar. The README is explicit that the dot has no built-in meaning: it "displays a colored dot. What the dot means and when to change it is up to you." That is the whole design. Green can mean passing tests, red can mean failure, and the mapping lives in your script, not in the app.

The audience is narrow and specific. You are on macOS, you already have a shell or a program that knows when a state changes, and you want that state visible without a notification banner, a sound, or a window. The README lists client libraries for Bash, Zsh, Fish, Go, Node, Deno, PHP, Java, Python, Ruby, Rust, Nim, Erlang, C, C#, Crystal, Emacs and AppleScript, which tells you the intended usage pattern: AnyBar is the display, and your language of choice is the driver. If you are not on macOS, the project does not apply to you. The README points to separate ports for Ubuntu Unity, i3wm, Windows 10 and Emacs, which are different projects with their own codebases.

The UDP control channel and what happens to your message

AnyBar listens on a UDP port, 1738 by default. There is no HTTP endpoint, no socket file, no CLI binary and no configuration file. The protocol is the payload: you send the bytes of a command name, and the app changes the dot to match. The README's example sends the word black:

sh
open -a AnyBar
echo -n "black" | nc -4u -w0 localhost 1738

The open -a AnyBar line launches the app first, because the README states that AnyBar.app must be running before any commands can be sent. The nc flags matter: -4u selects UDP over IPv4 and -w0 avoids waiting. The echo -n suppresses the trailing newline, so the datagram contains exactly the five bytes of black. If your shell lacks nc, the README offers a pure Bash form that writes to /dev/udp/localhost/1738.

The command set is a fixed list of names: white, red, orange, yellow, green, cyan, blue, purple, black, question, exclamation, filled and hollow. Sending quit terminates the app. There is no documented reply, acknowledgement or error channel. That is the trade-off of a UDP design: a dropped or malformed datagram produces no feedback, and the dot simply does not change. For a status light this is usually acceptable, since the next state update will correct it. For anything that must be confirmed, it is not.

Installing AnyBar and lighting the dot for the first time

The README offers two install paths. You can download the 0.2.3 zip from the GitHub releases page, or use Homebrew Cask:

bash
brew install --cask anybar

After installation, launch the app and send it a color. The README's own sequence is the shortest working example:

bash
open -a AnyBar
echo -n "green" | nc -4u -w0 localhost 1738

If the dot turns green, the channel works. A useful next step is a shell function so you can type a color as a command, which the README gives in two forms:

bash
function anybar { echo -n $1 | nc -4u -w0 localhost ${2:-1738}; }
anybar red
anybar green 1739

The function takes the color as the first argument and the port as an optional second argument, defaulting to 1738. That second argument is how you address a second instance. The README shows multiple instances launched with ANYBAR_PORT and open -na, for example ANYBAR_PORT=1739 open -na AnyBar. Two more environment variables are documented: ANYBAR_TITLE sets a label so you can tell dots apart, and ANYBAR_INIT sets the initial color. Custom images go in ~/.AnyBar; the README says images should be 19x19 pixels, or 38x38 for the @2x retina variant, and that sending the file's base name displays it.

Where AnyBar stops being the right tool

The dot has no memory. AnyBar shows current state and nothing else. If your build failed twenty minutes ago and then a later step set the dot to green, the failure is gone from the display. There is no log, no history view, no timestamp and no way to ask the app what it is currently showing over the same channel. The README documents one read path, and it runs the other direction: an AppleScript snippet can get image name from the app and show it in a notification, but that is a separate automation layer, not a status API.

UDP on localhost is also unauthenticated. Any process on the machine that can open a socket to port 1738 can change your dot. On a single-user laptop that is a trivial concern; on a shared or multi-tenant host it means the indicator is advisory only and should not be trusted as a security signal. Finally, the platform boundary is absolute. The README's ports section lists Ubuntu Unity, i3wm, Windows 10 and Emacs implementations as separate projects. If your team is mixed-platform, AnyBar covers only the macOS half, and you will be maintaining two status mechanisms or standardizing on something else.

AnyBar against a general notification or tray tool

The closest alternative in spirit is a menubar app that accepts richer input, such as a tray utility driven by a local HTTP API or a full notification system that can post banners with titles and bodies. The difference in approach is the data model. AnyBar's model is a single enumerated value with a fixed vocabulary of thirteen names plus whatever images you drop into ~/.AnyBar. A notification tool's model is a message with text, priority and often an action button. If you want to read the state at a glance from across the room, the single dot is faster to parse than a line of text. If you want to know what failed, AnyBar cannot tell you, and you will be back in the terminal anyway.

A second comparison is a terminal multiplexer status line or a shell prompt segment. Those live inside your terminal, so they disappear when the terminal is hidden or closed, which is exactly the case AnyBar was built for. The cost of moving the indicator to the menubar is that it becomes global: one dot, shared by every script that writes to the port, with no built-in namespacing. The README's answer to that is multiple instances on different ports, each with its own ANYBAR_TITLE. That works, but it is manual bookkeeping you have to maintain in your scripts.

Maintenance, releases and the licence

The repository is not archived, and the last push was on 2026-03-21. The most recent release is 0.2.3 from 2021-02-18, preceded by 0.2.2 in 2020-11-03 and 0.2.1 in 2020-08-28. The gap between the last release and the last push is worth noting if you depend on packaged builds: the release channel has been quiet for years even though the repository has seen activity since. The README does not document an upgrade procedure, and it does not state whether ANYBAR_PORT, ANYBAR_TITLE and ANYBAR_INIT are stable across versions. The CHANGELOG.md file exists at the repository root, so that is where to check before upgrading.

The licence is EPL-1.0, the Eclipse Public License. It is a weak copyleft licence, which in practice means you can use AnyBar alongside proprietary code, but modifications to the licensed code itself carry obligations. This is not legal advice; read the LICENSE file at the repository root if you plan to redistribute a modified build. For the common case of calling the app from your own scripts over UDP, the licence question is about the app you install, not about your scripts.

Editorial conclusion

Adopt AnyBar if you want a single status dot on macOS that any script, language or CI step can drive with one UDP datagram, and if you accept that the dot carries no history, no labels beyond an optional title, and no alerting. Do not adopt it if you need a Windows or Linux tray, a queryable status API, or a widget that survives a crash with state intact. Before wiring it into a workflow, verify the port you intend to use is free, confirm the exact color names the README lists, and check what your firewall does with inbound UDP on localhost.

Frequently asked questions

How do I install AnyBar on macOS?

Either download the 0.2.3 zip from the GitHub releases page, or run brew install --cask anybar. The README lists both options and notes that the app must be launched before any commands can be sent.

Which port does AnyBar listen on, and can I change it?

The default is UDP port 1738. The README documents the ANYBAR_PORT environment variable for changing it, and shows running several instances with ANYBAR_PORT=1739 open -na AnyBar and similar.

Can I run more than one AnyBar instance at the same time?

Yes, as long as each listens on a different port. The README shows ANYBAR_PORT combined with open -na to launch several instances, and ANYBAR_TITLE to give each dot a label so you can tell them apart.

How do I use a custom image instead of the built-in colors?

Place the image in the ~/.AnyBar directory and send its base name to the port. The README specifies 19x19 pixels for standard resolution and 38x38 for the @2x retina version.

Official sources

  1. Issues
  2. License: EPL-1.0
  3. README
  4. Releases
  5. tonsky/AnyBar on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/tonsky-anybar.svg)](https://hysenlabs.com/projects/tonsky-anybar)