最近这段时间,我在开发机上几乎天天都在用 BrewUI。以前管理 Homebrew 全靠终端敲命令,包一多真的会烦:搜索要看一堆输出、升级列表密密麻麻、依赖关系不画图根本理不清。BrewUI 这个最近在开发圈里讨论度很高的开源工具,本质上是给 Homebrew 做了一层图形化界面,解决了“命令能做的我不想记,界面能看的我不想猜”的问题。这篇文章我就从实际使用体验出发,把 BrewUI 能做什么、怎么装、怎么用、会遇到什么坑,一次性讲清楚。
我先把结论放在前面:BrewUI 适合那些经常用 Homebrew 装包、但又不想整天面对终端的开发者。它不是要取代命令行,而是把 Homebrew 的核心能力变成可视化的操作台。尤其当你安装的包超过几十个、服务又多、动不动还要清理磁盘空间的时候,BrewUI 能帮你省下大量对着一堆命令行输出数包的时间。
1. 为什么 Homebrew 需要一层图形界面
1.1 终端里的痛点被放大的场景
Homebrew 本身已经很好用了,brew install、brew update、brew upgrade这几个命令足够应付日常。但真实开发环境里,问题不会这么简单。比如你装了几十个包之后,想看看某个包到底被谁依赖,终端里跑brew deps --tree能输出树状结构,问题是结构一长就完全看不下去;再比如升级包的时候,brew outdated列出的列表包含版本号、过期时间、依赖变动,纯文本形式根本不好筛选,升级完又不知道哪个包产生了额外依赖、哪个包已经没人用了。
还有一个特别头疼的场景是升级策略。全量brew upgrade会把所有过时包都升级一遍,耗时很长,而且有些包的升级会引入不兼容的依赖。我见过很多同事直接在终端无脑跑brew upgrade,结果升级完一个开发依赖,把整个项目环境搞挂了。这时候 GUI 的价值就出来了:升级前可以清清楚楚看到“这个包会连带升级哪些依赖”,而不是等命令跑完才知道发生了什么。
1.2 现有的同类工具各自有硬伤
BrewUI 不是第一个做 Homebrew GUI 的项目,以前有 Cakebrew,也有更偏专业的 Cork。Cakebrew 的问题在于开发节奏太慢,界面停留在很多年前的风格,对新的 Homebrew 特性支持不足,比如brew services或依赖关系展示就很弱。Cork 做得更系统,但配置门槛高,它是给那种“连 GUI 都要高度自定义”的极客准备的,普通开发者上手会觉得绕。
BrewUI 的定位刚好取中间:界面走原生 macOS 风格,功能覆盖搜索、安装、卸载、更新、清理、服务和依赖关系,开箱即用。它的底层逻辑并不复杂,就是在图形界面里调用 Homebrew 这个“引擎”,再把结果用列表、详情、日志的方式呈现出来。用一句大白话说,BrewUI 就是把原本需要用命令行查询、筛选、确认的活,换成了点按钮和看表格。
2. 看懂 BrewUI 的整体设计
2.1 它到底长什么样
第一次打开 BrewUI,你会看到一个典型的 macOS 主界面,大致分成几个区域:
- 左侧是导航栏,包含仪表盘、已安装的包、更新列表、搜索、服务、清理工具、日志。
- 中间主体区是按列表展示的包信息,每一行能看到包名、当前版本、最新版本、状态。
- 右侧或底部是详情面板,展示选中包的依赖关系、安装路径、相关文件、可用版本。
- 顶部是操作按钮,安装、升级、卸载、重新安装、锁定版本等等。
这个布局和 Xcode 的 Organizer、系统设置的侧边栏风格接近,macOS 用户基本不需要学习成本。我比较喜欢的是它把“更新列表”单独抽出来了,所有可升级的包集中在一个页签里,每行还能显示这个版本的更新说明,这比在终端看brew outdated舒服太多。
2.2 原生应用路线带来的体验优势
从技术实现上看,BrewUI 面向 macOS 开发,走的是原生应用路线。这一点很重要,因为 Homebrew 本身就是 macOS 生态里的工具,GUI 客户端如果做成网页套壳(Electron 那类),内存占用会很难看。原生应用启动速度快、界面响应流畅,而且可以很好地调用系统能力,比如访问钥匙串、读取 Homebrew 日志文件、监听文件变化刷新状态。
使用原生技术栈还有一个额外好处:安装包体积可以控制得很小,不像某些 Electron 工具体积随随便便几百兆。BrewUI 的发布包里只包含 App 本体和少量资源文件,日常运行内存占用控制得也不错。
2.3 和 Homebrew 的协作方式
BrewUI 本质上没有绕过 Homebrew,它只是在 Homebrew 外面套了一层壳。具体工作方式是这样的:
- UI 操作触发对应的
brew子命令,比如安装一个包,实际上就是在后台执行brew install 包名。 - 命令执行过程中的标准输出、标准错误输出会被实时捕获,显示在界面的日志面板里。
- 执行结束后,BrewUI 调用
brew list --json=v2或brew info --json=v2这类 JSON 输出指令,重新读取包列表和详细信息,刷新界面状态。
这种“UI 直接驱动命令行”的架构其实是最稳妥的方案。Homebrew 本身功能太复杂,如果绕过命令行直接操作本地数据库和文件目录,很容易在版本升级后出兼容性问题。而通过命令行接口调度,底层无论怎么变,只要 CLI 兼容,GUI 就能正常工作。我在使用中确实遇到过 Homebrew 升级后 UI 暂时异常的情况,但大多数时候只要升级 Homebrew 后重启 BrewUI 就恢复了,这正说明 CLI 接口的稳定性是它的兜底保障。
3. 环境准备与安装流程
3.1 动手前先确认基础环境
BrewUI 不是独立工具,它依赖系统里已经装好的 Homebrew。所以在安装 BrewUI 之前,先在终端里确认一下 Homebrew 环境是完整的。可以用下面几个命令做基础检查:
brew --version xcode-select -p brew configbrew --version确认 Homebrew 已安装且版本正常。xcode-select -p确认 Xcode Command Line Tools 路径存在,如果返回值不是/Library/Developer/CommandLineTools或类似路径,说明命令行工具没装好。brew config会输出 Homebrew 的很多配置信息,包括 macOS 版本、CLT 路径、安装目录、构建工具等。我一般会重点看HOMEBREW_PREFIX这一行,它决定了 Homebrew 的实际安装位置。
这里顺便提一句:Intel Mac 上 Homebrew 默认装在/usr/local,Apple Silicon 上默认装在/opt/homebrew。BrewUI 在启动时会自动检测常见路径,但如果你用的是自定义安装位置,需要在设置里手动指定brew可执行文件的路径。
3.2 安装 BrewUI 的两种方式
BrewUI 目前的主要分发渠道是 GitHub Releases,下载.dmg文件,拖入“应用程序”文件夹即可完成安装。这个流程没什么特别,和其它 macOS 软件一样,唯一要注意的是如果你的 macOS 版本比较老,需要检查一下最低系统版本要求。
如果项目后续提供了brew install --cask brewui之类的安装方式,那会更方便,但目前我实际使用下来,还是推荐直接下载 Release 版本。理由很简单:Cask 方式虽然能自动升级,但版本更新频率未必跟得上项目仓库的节奏,而且有些预览版功能不会第一时间进 Cask。自己在 Releases 页面盯版本反而更直观,想回退也方便。
安装完第一次启动时,macOS 的 Gatekeeper 可能会拦截未签名或没经过公证的应用。遇到这种情况,不需要急着关闭系统保护,在“系统设置”->“隐私与安全性”里找到对应提示,手动允许即可。要是你明确信任这个工具,也可以在终端里执行:
xattr -dr com.apple.quarantine /Applications/BrewUI.app这个命令会把隔离属性去掉,但我的建议是只在了解风险的情况下使用。
3.3 首次启动的设置细节
首次启动 BrewUI 后,它会自动搜索 Homebrew 安装路径。如果一切正常,你会在仪表盘看到 Homebrew 的版本号、安装目录、运行状态。如果界面提示找不到 Homebrew,可以在“设置”里手动指定brew的可执行文件位置,一般是/opt/homebrew/bin/brew或/usr/local/bin/brew。
设置完成后,BrewUI 会开始扫描已安装的包。第一次扫描可能比较慢,因为它要读取大量包的信息并解析 JSON 数据。扫描完成后,界面上会显示包的总数、已安装的应用数量、命令行工具数量、需要升级的包数量等。这一步只要耐心等几十秒就好,后续启动都会快很多,因为会有本地缓存。
4. 日常使用实操:搜索、安装、升级
4.1 搜索安装一站搞定
BrewUI 的搜索框在顶部导航栏,输入关键词后会自动联想。这个搜索背后走的是brew search的能力,但呈现方式比终端好太多:每个结果会标注是 formula(命令行工具)还是 cask(图形应用),还会显示简要描述。
选中搜索结果后,右侧详情面板会展示这个包的维护状态、版本、依赖项、许可证等信息。这时候点“安装”按钮,BrewUI 会开始执行brew install,同时在日志面板实时刷新输出。我经常用这个功能装一些临时工具,比如wget、jq、yq、ripgrep,装完就能立刻在任意终端使用。
有一点要提醒:BrewUI 安装 cask 类型应用时,本质上是执行brew install --cask 应用名。有些 cask 在安装过程中需要输入管理员密码,这是因为它们要复制到/Applications目录。BrewUI 会弹系统级授权框,这是正常的,不用担心。
4.2 有选择地升级而不是无脑 all in
终端里跑brew upgrade虽然简单,但把所有包全部升级其实是一个高风险操作。BrewUI 的更新页签会把所有可升级包列成表格,每一行显示当前版本和最新版本,部分包还会展示版本更新时间。你可以挨个看,只选需要升级的包,然后点击“升级选中”。
我的习惯是:像wget、curl、git、jq这类纯净工具可以直接升级;像node、python、openssl这类会被项目依赖的包,升级前一定要看看有没有连带依赖变动。在 BrewUI 里点击某个包,详情面板会显示依赖树,能直接看到升级它会连带升级哪些包。这个信息在终端里要跑brew outdated --verbose加brew deps --tree才能拼出来,现在一个界面全解决了。
如果你确实想全量升级,BrewUI 也有“全部升级”按钮,但我建议升级前先手动执行一次数据备份或快照。尤其是开发机器,环境说坏就坏,留个后手总没错。
4.3 升级后的日志留痕
BrewUI 在执行安装或升级时,会把完整日志写到本地目录,方便排查问题。默认日志位置是:
~/Library/Logs/BrewUI/每个操作会生成独立的日志文件,命名规则大概是“操作类型_包名_时间戳.log”。比如你执行了一次nginx的升级,会看到一个像upgrade_nginx_20250115_103000.log这样的文件。如果你遇到安装卡住、依赖冲突、编译失败之类的问题,把日志拖给别的开发者看,大家能快速定位到问题来源。
这一点平时没感觉,真出了事能救命。有一次我用终端手动装了某个带编译过程的包,报错信息在终端里滚屏很快,根本来不及截图。后来改用 BrewUI 看日志文件,才发现是缺少某个编译依赖,按日志提示装上之后就正常了。
5. 进阶功能:清理、依赖关系、服务管理
5.1 依赖关系可视化,看清谁在依赖谁
如果说搜索安装是 BrewUI 的基础功,那依赖关系可视化就是它的核心亮点。Homebrew 里有几组命令可以查依赖,比如:
brew list --installed列出所有已装包。brew deps --tree 包名输出某个包的依赖树。brew uses 包名查看哪些包依赖它。
这些命令在终端里输出很乱,尤其是依赖树,层级一深就完全没法看。BrewUI 把依赖关系做成了可折叠的树状图,点开一个包,能看到它依赖的所有子包,还能展开二级、三级依赖。反查也很有用:选中一个包,点击“被谁依赖”,就会列出所有需要它的 formula 和 cask。
这个功能对排查环境问题特别有用。我碰过一个场景,想卸载一个老旧的libpng,但是怕其它包还在用它。在终端里要跑好几轮brew uses才能确认,在 BrewUI 里点一下“被谁依赖”,一目了然,确认没有包引用之后才敢清理。
5.2 无残留卸载与自动清理
日常用久了,Homebrew 会积累两类垃圾:一是升级时留下的旧版本文件,二是已经不被任何包依赖的孤儿依赖。终端里执行brew cleanup和brew autoremove可以处理,但什么时候跑、跑了会删什么、会释放多少空间,命令行里并不直观。
BrewUI 专门做了一个“清理工具”页面,会先扫描当前系统,展示可清理的缓存大小、旧版本数量、孤儿依赖数量。这个页面会明确告诉你会删哪些东西,而不是像终端命令那样直接动手。扫描结果出来后,你可以勾选要清理的类别,再点“执行清理”。
我对这个功能的建议是:缓存可以放心清,旧版本文件建议先看一下有没有需要回滚的场景,孤儿依赖清理前确认一下当前项目的环境。因为有些孤儿依赖可能正是某个项目编译时需要的,虽然现在没有被 Homebrew 的依赖关系引用,但删掉之后项目可能要重建。
5.3 服务管理,像操作面板一样简单
Homebrew 自带brew services子命令,用来管理后台服务,比如nginx、postgresql、mysql、redis等。但这个命令的输出信息密度低,状态查看和操作也不够直观。BrewUI 把服务管理做成了开关列表,每个服务一行,状态一目了然:
- 绿色表示正在运行。
- 灰色表示已停止。
- 黄色表示异常退出或注册了但没运行。
点击对应服务的按钮,可以直接启动、停止、重启服务。底层其实就是执行brew services start/stop/restart 服务名,优势在于你可以一次性看到所有服务的状态,不用逐个brew services list去看。
我日常开发主要用 PostgreSQL 和 Redis,以前经常忘记哪个服务开着、哪个服务挂了。用 BrewUI 之后,我启动电脑第一件事就是打开服务页签,确认数据库和缓存都在线,有异常直接点重启,比终端里敲命令少打好几个字。
6. 常见问题整理与排查思路
6.1 Homebrew 权限问题导致操作失败
现象:安装或升级时提示Permission denied、Failed to write,或者“目录只读”。
原因:Homebrew 目录权限不正确,通常是之前用sudo运行过brew命令,导致部分文件所有者变成了 root,普通用户无法写入。
排查命令:
ls -l /opt/homebrew如果发现大量文件的拥有者是root,说明权限被搞乱了。
解决办法:先用sudo chown -R 当前用户名 /opt/homebrew把目录所有权改回来。这一步只针对你自己机器上的 Homebrew 安装目录,千万别对整个系统目录执行。如果权限问题很普遍,也可以执行brew doctor,看它有没有给出修复建议。
6.2 BrewUI 启动后列表一直刷新不出来
现象:打开 BrewUI,包列表一直转圈,始终加载不出来。
原因:最常见的是 Homebrew 源访问慢,或者本地网络环境受限。BrewUI 在启动时要调用brew list --json=v2、brew update等命令,如果这些命令在终端执行都卡顿,UI 自然跟着卡。
排查思路:先在终端手动执行:
brew list --json=v2 | head -c 100如果这条命令都产出很慢,那问题一定在网络或 Homebrew 源上。解决办法一般是把 Homebrew 的下载源换成国内镜像源,比如清华源、中科大源。换源后升级和列表读取速度会明显改善。如果换源后依然慢,确认一下终端里的代理设置是否影响了本地回环地址,但这里我不展开说网络细节,遵守规范。
6.3 包状态显示和终端不一致
现象:在终端里手动执行了brew install,但回到 BrewUI 界面,新包没有出现在列表里。
原因:BrewUI 不会自动实时监控 Homebrew 目录,它是按需刷新或定时刷新。界面上显示的是上次扫描的结果,所以和终端状态不一致。
解决办法:手动点击界面上的刷新按钮。BrewUI 大部分版本都支持下拉刷新或快捷键刷新,刷新后会重新读取 Homebrew 数据。为了避免这种不一致,我的习惯是尽量只在 BrewUI 里管理包,要么就只在终端里操作,不要两边交叉使用。两边交叉操作不是会出错,但会把状态搞得很难捉摸。
6.4 同时执行多个耗时长命令时 UI 卡顿
现象:BrewUI 正在执行一个大包安装或升级时,点击其他按钮没有响应,界面像假死。
原因:BrewUI 的执行队列是一次只能跑一个 brew 任务的模式。这种设计其实是为了安全,因为 Homebrew 自身对并发支持有限,多个 brew 进程同时操作本地数据库和文件时,可能产生锁冲突或目录写入竞争。卡顿是因为任务排队,而不是程序崩溃。
解决办法:耐心等当前任务结束。如果想减少排队,避免一次性勾选太多包批量升级。大项目升级建议拆成小批次,比如一次升级 5-8 个包。这不仅是给 UI 减负,也是给自己留观察错误的空间,哪一个包有问题能立刻定位。
6.5 日志文件过大,磁盘占用暴涨
现象:使用一段时间后,~/Library/Logs/BrewUI/占用空间变大。
原因:每次操作都生成独立日志文件,长期大量升级后,日志积累会很明显。
解决办法:定期清理日志目录,或者把日志级别调整为“仅错误”。Homebrew 本身也有日志目录~/Library/Logs/Homebrew/,这两个目录建议一起维护,清理老日志、保留近期日志即可。
7. 一些个人使用心得
在实际用了 BrewUI 几周之后,我最大的体会是:工具的价值取决于你原本的操作习惯。如果你是一个对命令行极其熟悉、每个包名都烂熟于心的人,BrewUI 对你的增益有限,毕竟快捷键和命令行的效率确实很高。但如果你管理着大量开发环境,或者经常要给别人调试机器,BrewUI 的界面化操作能明显降低出错率,也能让不熟悉命令行的同事快速上手。
我现在的工作流是:日常搜索、安装新包、清理缓存、管理服务用 BrewUI,特殊场景比如排查复杂编译问题、查看特定包的 formula 定义时,还是会打开终端手动执行命令。两者配合起来,比纯命令行高效不少。最后再分享一个小技巧:BrewUI 里如果某个包被误升级导致项目出问题,别慌,在详情页找到旧版本入口直接降级。这个操作在终端里可能要翻历史日志找版本号,在 BrewUI 里几下就能完成,关键时刻能省下大量复盘时间。如果你经常折腾开发环境,BrewUI 值得放进你的工具清单里。