StackBar icon

Free macOS menu bar app

StackBar

Installed vs latest runtime versions, always one glance away

See Bun, Flutter, Node, and Python versions on your machine, check for newer stable and LTS releases, and update them with a click.

v2.2.1 · 14.0 MB · macOS · Apple silicon · free for personal and public use

What it does

Runtime versions at a glance

  • Live installed vs latest for Bun, Flutter, Node (nvm), and Python
  • One-click update per runtime
  • Periodic checks with a badge when updates wait

Version history

StackBar release notes

Every published version, newest first.

  1. v2.2.1

    Current9 Nov 2026
    • A check without internet no longer hides pending updates. When the latest versions couldn't be fetched (offline, a site down), every tool lost its known latest version: the header said `All up to date`, the orange rows turned gray and the badge cleared until the next check, hours later. StackBar now keeps the latest versions it already knew, and with none known says `Couldn't check for updates` instead of "All up to date". Each row's submenu still shows what failed.
    • "checked …" on Refresh shows the time of the check. It said `checked just now` for hours, because the menu is only rebuilt at the next check. It now shows the time, `checked 14:05` (`yesterday 14:05`, `Nov 7, 14:05`), which stays true.
  2. v2.2.0

    8 Nov 2026
    • A menu bar icon drawn from the StackBar logo. The three stacked layers inside the ring, as on entelxcore.com, instead of a generic system symbol. When nothing needs attention it still takes the menu bar's own color, light or dark, and it shows the number of updates, as before.
    • A clearer menu. Each tool is one row: a status dot (orange with an update, a half dot in your accent color while it updates or waits in Update all, gray otherwise), the name, and its version in a right-aligned column, such as `24.20.0 → 24.22.1` or `1.4.4`. The header, with the app's logo, says how many updates there are, and when the versions were last checked now shows on the right of Refresh.
    • The new teal logo. The app's icon is now the teal StackBar logo from entelxcore.com.
  3. v2.1.0

    8 Nov 2026
    • Update all. When two or more tools have an update, Update all (N)… appears at the top of the tools list. One confirmation lists every tool with its current and target version and how it is updated (including Java's link into `~/Library/Java/JavaVirtualMachines`), then StackBar updates them one after another, never side by side: Java and Python both run `brew update`, and two Homebrew runs at once fail on Homebrew's lock. The menu's first line shows how far it is (“Updating 2 of 4: Java (JDK)…”); the tool being updated reads “updating…” and the ones still waiting “queued…”. A failed update does not stop the others, and at the end you get one summary of what was updated, what failed (with the error line) and any step left for you: a notification when everything went through and notifications are on, otherwise an alert.
    • An Update clicked while Update all runs waits its turn. Clicking a row's Update, Install or Update Flutter with --force… during Update all asks for confirmation as usual, then queues it behind the others instead of starting a second update next to them; it is included in the summary. Update all itself waits for an update you started by hand: it says which one is still running.
    • Show last update log. Alerts only had room for the end of an update's output (400 characters, 1,200 for an error), which was rarely enough to see why it failed. StackBar now keeps each tool's full update output in `~/Library/Application Support/StackBar/update-logs/<tool>.log`: every command it ran, when it started, its exit status, its PATH and its complete stdout and stderr, the newest run first and the last 5 runs (at most about 1 MB) kept. Each row's submenu offers Show last update log… once a log exists, and an update's failure alert has a Show Log button. Logs open in your default text editor (TextEdit unless you changed it), which opens straight away at the newest run and lets you search and copy; Console is built for the system log and opens a plain file in a separate, slower log-report view.
    • A failed update's message starts with the error. It started with whatever partial line the last 1,200 characters of output began with. It now starts with the line that names the error (for example Homebrew's “Another active Homebrew update process is already in progress”), followed by the end of the output.
  4. v2.0.4

    7 Nov 2026
    • The Node row shows nvm's default Node, the one its Update changes. StackBar took whichever `node` came first on PATH. With a lazy-loaded nvm (oh-my-zsh's lazy mode, zsh-nvm), or when your interactive shell could not be read, that was Homebrew's `/opt/homebrew/bin/node`, which `nvm install --lts` never touches, so the row could describe a Node the Update button never changes. Whenever nvm is installed, the row now follows nvm's `default` alias, including the `lts/*` → `lts/<name>` → version chain StackBar's own update writes, and picks the newest version by number (v24.21.0 over v24.9.0, which a plain text sort got wrong). If Terminal's PATH would find a different `node` first, the row's note names it and its version.
    • A `JAVA_HOME` set in your shell profile is no longer missed. With `export JAVA_HOME=$(/usr/libexec/java_home -v 17)` and only Apple's `/usr/bin/java` on PATH, Terminal runs JDK 17, but StackBar read only PATH from your shell and showed the newest JDK as “up to date”. StackBar now reads `JAVA_HOME` from the same login-shell run as PATH (no extra shell started), shows the JDK Terminal really runs, and when it is older than the installed LTS names the profile line to change, as it already did for a PATH pin.
    • Java versions without a dot are read. A GA JDK is versioned `25`, not `25.0.0`: its `release` file, `java -version` (`openjdk version "25"`) and Homebrew's openjdk formula at a GA release all left the row at “installed · Could not parse”, or dropped the Homebrew version. A bare feature number is now accepted where the value is a Java version, and nowhere else.
    • A row being updated stays “Updating…”. A refresh while an update was running (the timer, or Refresh) redrew that row with its Update item again, and clicking it did nothing; a second update finishing did the same to the first. A refresh that started before an update finished could also put the old version back on screen afterwards. Rows keep their busy state until their own update ends, and a finished update's result is never replaced by a refresh that started before it.
    • The Xcode Python row no longer names Python 3.14. It read “Not upgradable — 3.14 is Homebrew Python” on Macs where Homebrew Python is 3.15. It now names the Homebrew Python actually installed, or says it is part of Xcode / Command Line Tools when there is none.
    • The menu bar icon is visible on a light menu bar. It was drawn white, so it disappeared on a light menu bar (a light wallpaper, or Reduce Transparency). When nothing needs attention it is now a template image, drawn black or white to match the menu bar and redrawn when that changes; the update colors and the update dot are unchanged.
    • Settings and cached versions survive an interrupted save. `state.json` was rewritten in place, so a save cut short left it empty or half written and the next save lost your settings. It is now written to a temporary file in the same folder and swapped in only once complete.
  5. v2.0.3

    7 Nov 2026
    • Apple's Python and a Node that nvm does not manage no longer offer an update that can only fail. On a Mac whose only `python3` is Apple's (Xcode / Command Line Tools), the Python row read “● Python (Apple) 3.9.6 → 3.15.2”, tinted the menu bar icon, counted as an update in notifications, and its Update ended in “Homebrew was not found” (with Homebrew, it installed a different Python than the one shown). A Node installed without nvm did the same as “Node (nvm)”, failing with “nvm was not found”. Both rows now show the installed version with a note on how that copy is updated, and no badge, tint or notification. The Python menu offers Install Homebrew Python… only when Homebrew is installed (for python.org's Python too) and links Homebrew's install docs otherwise; the Node menu links nvm's install docs.
    • Updating a Firebase CLI installed with npm under Homebrew's Node no longer installs a second copy. StackBar took any `firebase` under `/opt/homebrew` for Homebrew's `firebase-cli` formula, so an `npm install -g firebase-tools` made with Homebrew's Node was compared with the formula's version, and Update ran `brew install firebase-cli` next to it. Only the formula itself now counts as a Homebrew install; an npm package is compared with npm's latest and updated with the npm of the Node it belongs to.
    • Launch at login no longer starts a second StackBar, or quits the one you are using. Turning it on loaded the login item right away, and since it starts at load, a second StackBar appeared next to the first; turning it off unloaded the item, which stops StackBar when it was the copy started at login. The setting now only adds or removes the login item, which macOS uses at the next login.
    • A failed update no longer leaves StackBar closed. If installing an update failed after StackBar quit, nothing reopened it. The installer now reopens the installed StackBar whenever it cannot finish, and an update that could not be installed at all (StackBar opened from the temporary location macOS uses for downloads, or an Applications folder this user cannot write) is refused before StackBar quits, with a message saying why.
    • “Update took too long … was cancelled” now really cancels. The download kept going after that message and could quit StackBar and install minutes later. A cancelled update now stops, and the timeout only counts time without download progress, so a slow connection is no longer cut off.
    • An update containing more than one StackBar.app is refused. The signature check and the installer each picked a bundle on their own; with exactly one allowed, the installer can only install the bundle that was checked.
  6. v2.0.2

    7 Nov 2026
    • Updating Node keeps your global npm packages. nvm keeps global packages (firebase-tools, serve, …) per Node version, and the update ran a plain `nvm install --lts`, so they stayed behind in the old version and disappeared from Terminal. The update now reinstalls them into the new LTS from your previous default (`--reinstall-packages-from`), unless the default already is that LTS.
  7. v2.0.1

    7 Nov 2026
    • The Python row shows the Python its Update button changes. StackBar read whichever `python3` came first on PATH but updated Python with Homebrew. The python.org installer puts its own folder first on PATH (in `~/.zprofile`), so the row showed python.org's 3.14 with an update to 3.15 that `brew upgrade python` could never apply, while Homebrew already had 3.15. The row now describes Homebrew's `python3` whenever Homebrew has one. A Mac with only python.org's (or pyenv's) Python sees it as Python (python.org) with no update offered: the menu opens python.org's downloads instead, or installs Homebrew Python.
  8. v2.0.0

    7 Nov 2026
    • Signed with Developer ID and notarized by Apple. StackBar was ad-hoc signed, so macOS blocked the first launch until quarantine was cleared in Terminal or the app was opened with right-click → Open. It is now signed with ENTELXCORE's Developer ID Application certificate, with the hardened runtime, and notarized and stapled by Apple: it opens with a double-click like any other app. Because the signature now stays the same from version to version, access you grant it under Privacy & Security carries over to updates instead of being lost with each new build.
    • Opens on macOS 13 and later, as the README says. Release builds were made with Homebrew's Python, which is built for the Mac's own macOS, so 0.2.10 needed macOS 27 to open at all. Releases are now built with Python from python.org, the app declares macOS 13 as its minimum, and `release.sh` checks every bundled binary against it before publishing.
    • Updates must be signed by the StackBar developer. Check for Updates… now unpacks the downloaded zip and checks, before StackBar quits, that the app inside is signed with ENTELXCORE's Developer ID. A tampered or broken download ends in an “Update failed” alert and the current version keeps running.
  9. v0.2.10

    9 Oct 2026
    • You now see when an update is out. When the background check finds a new version, the “Update available” dialog (Install & restart… / Not now) now opens by itself, in front of other windows, once per version. Until now it only posted a notification, which macOS never showed.
    • Notifications go through Apple's current API (UNUserNotificationCenter). rumps used the deprecated NSUserNotificationCenter, whose notifications current macOS drops without an error. macOS only shows them for Developer ID signed apps; this ad-hoc build logs the reason to its error log instead.
    • HTTPS works on Macs without Homebrew: the bundled OpenSSL only looked for certificates in Homebrew's folder, so requests (update checks included) failed certificate verification there. macOS's own `/etc/ssl/cert.pem` is now trusted as well.
  10. v0.2.9

    9 Oct 2026
    • The app now bundles Python 3.14.8 (was 3.13.7), with `packaging` 26.3 and PyInstaller 6.22.3. `requirements.txt` now allows `packaging` 26.x (was capped below 26).
  11. v0.2.8

    25 Sep 2026
    • A shell rc line that pins PATH or JAVA_HOME to another JDK (Homebrew's `openjdk@21` caveat line, for example) keeps `java` on that one after the LTS is installed. StackBar now detects it, shows the file and line in the Java submenu and confirm dialog, and after the update pops an alert with the exact line to change instead of a “ready” notification. It never edits your dotfiles.
  12. v0.2.7

    25 Sep 2026
    • Firebase CLI (`firebase-tools`) joins the tracked stacks, listed after Node. The installed version is read from the package's `package.json` (no slow `firebase --version`), the latest comes from npm's `latest` tag with a GitHub fallback, and a Homebrew install compares against the `firebase-cli` formula instead.
    • Update Firebase CLI… matches how it was installed: `npm install -g firebase-tools@latest` with the npm that owns it, `brew upgrade firebase-cli` for Homebrew, or the firebase.tools upgrade script for the standalone binary. A root-owned system copy (nodejs.org installer in `/usr/local`) cannot be replaced without sudo, so the update installs into your nvm Node instead, which shadows it on PATH. Install Firebase CLI… uses npm from your nvm Node.
    • Java (JDK) joins the tracked stacks, listed after Firebase CLI. Installed = the JDK `java` on PATH runs, or the one `java_home` picks when that is Apple's `/usr/bin/java` stub; the version and vendor come from the JDK's `release` file. Latest = the newest GA of the current LTS line (Adoptium feed), capped at what Homebrew's `openjdk@<LTS>` formula ships.
    • Update Java (JDK)… runs `brew install openjdk@<LTS>` (or upgrade) and links it into `~/Library/Java/JavaVirtualMachines`, which `java_home` scans, so `/usr/bin/java` switches to it without an admin password. Existing JDKs (Oracle, Temurin, SDKMAN) stay installed.
  13. v0.2.6

    16 Sep 2026
    • Auto-check for StackBar updates every 6 hours (was 12). A failed check (offline right after login, server error) is retried up to 3 times, 10 minutes apart, instead of waiting for the next interval.
    • Source installs need Python 3.10+: `install.sh` skips Apple's bundled 3.9 and rebuilds a virtualenv created with it (the .app is unaffected).
    • The first silent update check really waits a minute after launch. rumps timers fire as soon as they start, so it used to run immediately — twice — often before Wi-Fi was up after login.
  14. v0.2.5

    16 Sep 2026
    • Update Python… no longer fails with “Error: python not installed” on machines that only have an older `python@3.x` from Homebrew. `python` is a Homebrew alias for the current default, so the updater now falls back to `brew install python` when `brew upgrade python` reports it is not installed.
  15. v0.2.4

    12 Sep 2026
    • Auto-check for StackBar updates every 12 hours (first check about a minute after launch). A purple dot on the menu-bar icon plus a notification when a new version is ready; Check for Updates… becomes “Update x.y.z available…”.
  16. v0.2.3

    12 Sep 2026
    • Quit no longer reopens StackBar. Launch at login used `KeepAlive`, so launchd started the app again. Match RunBar: `KeepAlive` off, unload the login item on Quit (plist stays for the next login).
  17. v0.2.2

    27 Aug 2026
    • Settings… groups check interval, notifications, and launch at login. Menu chrome matches the other Bars (Check for Updates…, Version, Quit). Refresh now is now Refresh.
    • After a self-update, do not reload the LaunchAgent (that started a second icon). Launch at login still uses the same plist at the next login.
  18. v0.2.0

    22 Aug 2026
    • Flutter upgrades offer Update with --force… (`flutter channel stable && flutter upgrade --force`) next to the normal upgrade
  19. v0.1.7

    19 Aug 2026
    • Detect Flutter from the SDK on disk (`flutter.version.json`) so a slow or failing `flutter --version` no longer looks like “not installed”
    • Menu bar yellow/badge means update an installed stack, not “something is missing”
    • Missing stacks stay listed in the menu (with Install…) so you can add them; they do not tint the icon
  20. v0.1.6

    14 Aug 2026
    • Self-update starts the installer before parking any login item, verifies the new binary, then relaunches with `open`
    • Ignore `__MACOSX/*.app` stubs when unpacking the free-tools zip (same `ditto` zip layout as the other bar apps)
  21. v0.1.5

    13 Aug 2026
    • Relaunch after self-update uses LaunchServices `open` (not LaunchAgent bootstrap), so the menu bar icon comes back
  22. v0.1.4

    13 Aug 2026
    • Check for Updates shows the same “Installing update…” percent window as the other bar apps
    • Park the LaunchAgent before replacing the app so KeepAlive cannot reopen both the old and new copies
  23. v0.1.3

    13 Aug 2026
    • List Xcode / CLT Python next to Homebrew (informational — Apple does not allow upgrading it to 3.14)
    • `install.sh` picks the newest Python 3 from Homebrew or Xcode
  24. v0.1.2

    13 Aug 2026
    • Compare Homebrew Python against Homebrew bottles, not python.org
    • python.org-only patches (e.g. 3.14.7 while brew is 3.14.6) no longer look like a failed update
  25. v0.1.1

    13 Aug 2026
    • Track Homebrew Python next to Bun, Flutter, and Node
    • Skip Apple's `/usr/bin/python3` stub; update with `brew install python`
  26. v0.1.0

    13 Aug 2026
    • First release: menu bar versions for Bun, Flutter, and Node (nvm)
    • Checks latest stable / LTS every few hours (default 6)
    • One-click update per runtime
    • Launch at login, notifications, and StackBar self-update plumbing