Skip to content

Repository files navigation

BrewPackageManager Icon

BrewPackageManager

Native macOS Menu Bar App for Homebrew, redesigned as a first-class citizen in 3.0

macOS Swift License

BrewPackageManager is a native macOS menu bar companion for Homebrew that turns package maintenance, search, cleanup, diagnostics, and service management into a fast, readable desktop workflow instead of a collection of terminal commands.

The 3.0 line rebuilds the interface as a fully native macOS experience: system materials and vibrancy, automatic light/dark mode, the user's configured accent color, system typography, and standard controls everywhere. The popover keeps the fast four-tab flow, while the window mode becomes a real macOS management app with a grouped sidebar, in the spirit of Finder or System Settings.

FeaturesScreenshotsInstallationUsageDocumentationDevelopment


Screenshots

Overview

Overview

Window Mode

Window Mode

Package Search

Package Search

Tools

Tools

Services Management

Services

Dependencies

Dependencies

Package Detail

Package Detail

Statistics

Statistics

Settings Panel

Settings

Features

3.0 Native Shell

The 3.0 line replaces the custom dark theme with a fully native shell. The system decides the base colors and materials; the app only contributes state semantics (green for up to date, orange for pending, red for errors) on top.

  • Native by default: system materials, automatic light/dark mode, the user's accent color, system typography, and standard buttons, pickers, and forms
  • Popover: compact header with live status badge, native segmented tabs (Overview, Search, Tools, Settings), and push navigation with standard back buttons
  • Window mode: NavigationSplitView with a grouped sidebar — Packages (Overview, Search, Activity), Maintenance (Services, Cleanup, Dependencies), System (Statistics, Settings) — instead of a scaled-up popover
  • Contextual error banners: failures appear inside the affected screen with a retry action, replacing generic modal alerts

The four primary areas keep their roles: Overview is for action, Search is for discovery, Tools is for deeper management work, and Settings is for changing how the app behaves over time.

Package Management

Package management is still the center of the app, and 3.0 keeps the strong distinction between what is installed, what is outdated, and what is actually actionable. That matters because Homebrew setups often contain pinned packages, hidden updates, or items you want to keep around without turning them into constant visual noise.

  • Installed Package Visibility: installed Homebrew packages with version and update state
  • Visible Update Count: pinned and hidden updates are excluded from the main action count
  • Bulk Update Action: update all visible packages from the overview flow
  • Package Details: inspect metadata, versions, homepage, and release links
  • Pinned Guidance: pinned formulae stay visible as state, but are not treated as actionable updates
  • Hidden Items: hide noisy packages or updates and restore them later

In practice, this means the UI tries to stay honest. If something cannot be updated because it is pinned, the app should treat that as context, not as a broken action. If something is intentionally hidden, it should disappear from the main flow but still remain recoverable.

Search and Install

Search is designed for quick package discovery without leaving the menu bar flow. Instead of a one-shot input that forces an extra confirmation step, the search experience reacts while you type and keeps install and detail actions close to the result itself.

  • Live Search: search runs as you type
  • Type Filters: All, Formulae, or Casks
  • Direct Install: install packages from search results
  • Details Flow: open package details without losing the surrounding navigation context

This makes the screen useful both for fast installs and for cautious inspection. You can scan the result set, narrow by package type, open a package first, and only then install if it looks right.

Services

Homebrew services are one of the places where a GUI can save real time, especially when you are juggling local databases, queues, or background daemons. The app tries to surface the status of each service clearly enough that you can understand what is running before you touch anything.

  • Service Control: start, stop, and restart Homebrew services
  • Status Summary: running and stopped counts at the top of the screen
  • Row-Level Feedback: each service shows only valid actions for its current state
  • Metadata Visibility: service status, PID, and summary data stay readable in one card

The important part is not only that the action exists, but that the result is legible. A service screen should tell you whether something is running, who owns it, and what action makes sense next, instead of forcing you to infer that from raw command output.

Cleanup and Cache

Cleanup is intentionally split because Homebrew cleanup work is not all the same. Clearing the download cache, removing old package versions, and uninstalling packages are different actions with different consequences, and the UI should not blur them together.

  • Separated Actions: cache clearing and old-version cleanup are explicitly different flows
  • Immediate Cache Clear: clearing download cache does not ask for confirmation first
  • Old Versions Cleanup: destructive package-version cleanup still requires confirmation
  • Result Messaging: cleanup feedback explains what was cleared and what remains

That separation is there to reduce anxiety and avoid false expectations. If you clear cache, the app should say exactly that. If old versions remain, the app should say that too instead of making the user guess whether the action failed.

History and Diagnostics

When Homebrew behaves unexpectedly, the problem is rarely just “something failed.” Usually you need context: what command ran, whether it timed out, whether it was cancelled, what happened previously, and whether the app still has a sane internal state. This part of the app is there to make that debugging path much shorter.

  • Persistent History: operations are recorded for later inspection
  • Statistics View: high-level counts and success-rate summary
  • Command Diagnostics: debug mode keeps command output and metadata easier to reason about
  • GitHub Release Checks: manual and automatic app update checks against releases

This is especially useful when a workflow breaks after a Homebrew update. Instead of jumping immediately into guesswork, you can inspect what the app saw, what it tried to do, and where the failure surfaced.


Terminology

Homebrew uses two package families:

Those names come directly from Homebrew itself, so they appear in command output, JSON payloads, and the app UI. If you do not work with Homebrew terminology every day, it helps to map them to more familiar product language.

  • Formulae: CLI tools, libraries, and developer packages such as tree, wget, or python
  • Casks: macOS apps and app-like binaries such as visual-studio-code, google-chrome, or slack

If you prefer user-facing wording, think of them as:

  • CLI Tools = Formulae
  • Mac Apps = Casks

Requirements

The app targets a modern macOS setup and expects a standard Homebrew installation. It is intentionally opinionated here because predictable paths and a current toolchain make both runtime behavior and contributor support much more reliable.

  • macOS 15.0 or later
  • Homebrew installed at one of the standard paths:
    • /opt/homebrew/bin/brew (Apple Silicon)
    • /usr/local/bin/brew (Intel)
  • Xcode 26.5+ if you want to build from source with the same Swift 6.3.2 toolchain used in the current audit
  • Docker 29+ if you want to run the external audit lane locally

Installation

Download DMG

Download the latest release DMG from the releases page.

This is the simplest path if you only want to install and use the app. The DMG is meant to behave like a normal macOS distribution: drag, drop, open, and start using the menu bar extra.

  1. Open the DMG file
  2. Drag BrewPackageManager.app to the Applications folder
  3. Launch from Applications

Build from Source

git clone https://github.com/686f6c61/BrewPackageManager.git
cd BrewPackageManager
./create-dmg.sh

The DMG will be created at dmg/BrewPackageManager-3.0.1.dmg.

For public distribution outside your own machine, the recommended path is:

SIGNING_IDENTITY="Developer ID Application: Your Name (TEAMID)" \
NOTARYTOOL_PROFILE="bpm-notary" \
./create-dmg.sh

That release path signs the app bundle, signs the DMG container, submits the DMG with notarytool, and staples the notarization ticket back onto the final artifact when your credentials are configured.

Building from source is the better route if you want to inspect the code, test the new shell, or iterate on the app locally before packaging a release.

App Sandbox must be disabled for local builds and releases because the app needs to execute brew commands directly.


Usage

Open the App

  • Left-click the menu bar icon to open the main popover
  • Right-click the menu bar icon for quick actions such as refresh, app update check, opening the management window, or quit

The app is built around the menu bar first. Left click is the normal working surface, while right click is for quick utility actions when you do not need the full UI.

Update Packages

  • Open Overview
  • Review the visible update count
  • Use Update all visible when the overview shows actionable packages
  • Pinned or hidden updates are intentionally excluded from that action

This keeps the bulk update path deliberate. You get a quick answer to “what should I deal with now?” without mixing in pinned packages or intentionally hidden items that would only create friction.

Search and Install

  • Open Search
  • Type a package name such as tree, python, or mongodb
  • Use filters if you want only formulae or only casks
  • Install directly from the result card or open package details first

This flow is designed for both speed and caution. If you already know what you want, install is close at hand. If not, the package detail screen gives you enough context to inspect before making a change.

Use the Tool Screens

Open Tools for the deeper management surfaces:

  • Services
  • Cleanup
  • Dependencies
  • Activity
  • Statistics
  • Hidden Items
  • Help

This section is where the app keeps the heavier operational screens. The intent is to keep the main overview clean while still making advanced workflows available in one obvious place.

Settings

Open Settings to manage:

  • Launch at login
  • Automatic app update checks
  • Show only outdated packages
  • Debug mode
  • Auto-refresh interval

These settings are about runtime behavior, not decoration. They exist to help you decide how noisy, automatic, or verbose the app should be for your own Homebrew workflow.


Architecture

Technology Stack

  • Swift 6.3
  • SwiftUI
  • Observation
  • AppKit
  • OSLog

The stack is intentionally native. This app fits best as a lightweight macOS utility, so the architecture leans on SwiftUI for screen composition, AppKit for menu bar and window integration, and native concurrency/observation patterns for state flow.

Project Structure

BrewPackageManager/
├── Brew/              # Homebrew interaction & JSON parsing
├── Shell/             # Command execution infrastructure
├── Packages/          # State management & business logic
├── MenuBar/           # Status item and window/popover controller
├── UI/                # Native 3.0 interface
│   ├── Components/    # Reusable rows, badges, tiles, and banners
│   └── Screens/       # One focused file per screen
├── Settings/          # User settings persistence
├── Updates/           # GitHub release checks
├── Services/          # Homebrew services management
├── Cleanup/           # Cache & cleanup operations
├── Dependencies/      # Dependency analysis
├── History/           # Operation history & statistics
└── Utilities/         # Helper functions & AppKit bridges

Current Audit Reality

The 3.0 redesign resolved the main structural debt of the 2.0 line: the monolithic UI shell (1,600+ lines in one file) was replaced by a modular UI/ layer with a navigation model, shared components, and one focused file per screen. The remaining known debt is the decomposition of PackagesStore, which still concentrates package state, search state, and update checks.


Development

Build

./build.sh

Use the helper script if you want the fastest path to a local debug build with the expected project assumptions already baked in.

Or directly:

xcodebuild \
  -project BrewPackageManager/BrewPackageManager.xcodeproj \
  -scheme BrewPackageManager \
  -configuration Debug \
  ENABLE_APP_SANDBOX=NO \
  build

Tests

xcodebuild \
  -project BrewPackageManager/BrewPackageManager.xcodeproj \
  -scheme BrewPackageManager \
  -destination 'platform=macOS' \
  -derivedDataPath .derived-audit-2 \
  test

This runs the current unit and UI smoke suite. It is the minimum baseline before talking about packaging or release work.

Docker Audit

./scripts/audit-swift-in-docker.sh

The Docker lane is there to give us a repeatable external read on formatting, lint, and static analysis. It is especially useful when we want to separate “works locally” from “is actually clean enough to ship.”

This runs:

  • SwiftLint in Docker
  • SwiftFormat --lint in Docker
  • Semgrep in Docker

and writes logs to .audit-docker/.


Homebrew Commands Used

The app does not invent its own package-management semantics. It builds on top of Homebrew’s own commands and JSON output, then adds a native UI, state handling, and diagnostics around those flows.

# Package inventory and metadata
brew info --json=v2 --installed
brew outdated --json=v2
brew info --json=v2 <package>
brew search --json=v2 <query>
brew install <package>
brew uninstall <package>

# Services
brew services list --json
brew services start <service>
brew services stop <service>
brew services restart <service>

# Cleanup
brew cleanup --dry-run -s
brew cleanup -s
brew --cache

# Dependency inspection
brew info --json=v2 --installed
brew uses --installed <package>

The app also sets:

HOMEBREW_NO_AUTO_UPDATE=1
HOMEBREW_NO_INSTALL_CLEANUP=1

Credits

This project builds on ideas and infrastructure from BrewServicesManager by validatedev (MIT License), while the current 3.0 native UI is a new implementation.

Icon: Icons8 Box Icon

About

Native macOS menu bar application for managing Homebrew packages. Built with Swift 6 and SwiftUI.

Topics

Resources

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages