Guide
Updating Homebrew, npm, pnpm and uv on a Mac.
Every package manager on your Mac updates in its own way. This guide gives the command for each one, and how to check what's out of date first.
Update Homebrew, then upgrade
brew update and brew upgrade sound alike, but they do different things. brew update refreshes Homebrew and its list of available versions. brew upgrade installs the new versions. Updating alone changes nothing you installed.
# refresh Homebrew and see what's behind brew update brew outdated # upgrade everything brew upgrade # or one formula brew upgrade --formula node
Homebrew usually runs brew update by itself before an install or upgrade, so brew upgrade on its own is often enough.
Apps installed with Homebrew (casks)
brew upgrade covers apps too, with one catch: apps that update themselves are skipped by default. Add --greedy to include them.
brew outdated --cask --greedy brew upgrade --cask --greedy
Pin a version, and clean up
If a project needs a specific version, brew pin node keeps it out of upgrades until you run brew unpin node. Homebrew also removes old versions automatically, about every 30 days. brew cleanup does it now and frees the space.
Global npm packages
Packages installed with npm install -g live outside any project. Nothing updates them unless you run a command.
# see what's behind npm outdated -g # update all of them npm update -g
One package, or all of them
npm update -g moves every global package to its newest release. To update just one, install it again with @latest, for example npm install -g typescript@latest.
Global pnpm packages
pnpm works the same way:
pnpm outdated -g pnpm update -g --latest
--latest makes sure every package moves to its newest release. For one package, use pnpm add -g typescript@latest.
uv tools
Python command-line tools installed with uv tool install each live in their own environment. uv can list and upgrade them all.
# see what's behind uv tool list --outdated # upgrade one, or all of them uv tool upgrade ruff uv tool upgrade --all
A tool installed with a version specifier, like ruff<0.9, stays within it when you upgrade.
Codex CLI, Gemini CLI and other AI coding tools
Many AI coding tools are npm packages, so they fall behind like any other global package. Codex CLI is @openai/codex and Gemini CLI is @google/gemini-cli. Update them the npm way:
npm install -g @openai/codex@latest npm install -g @google/gemini-cli@latest
If you installed one with Homebrew instead, brew upgrade covers it. A Claude Code install from Anthropic's own installer updates itself, and claude update checks now. If you installed it with npm, update it the npm way.
To see how a tool was installed, run which codex, which shows where it lives. A path inside Homebrew's folder means Homebrew, and one inside a node folder means npm.
One list for every package manager
Four package managers means four sets of commands to remember. Greypaint checks them together. Under Tools it lists the Homebrew formulae and global npm, pnpm and uv packages that have an update waiting, next to your apps.
- It asks each one directly, using the same commands as above:
brew outdated,npm outdated -g,pnpm outdated -ganduv tool list --outdated. - It shows the installed version and the new one, with the part that changed highlighted, so a major jump stands out.
- Click Update next to a tool and it installs the newest version of just that one.
The same window also lists app updates. How that works is in updating with Greypaint.
Questions
What's the difference between brew update and brew upgrade?
brew update refreshes Homebrew itself and its list of available versions. It doesn't change anything you installed. brew upgrade installs the newer versions. Run update first, then upgrade.
How do I see which global packages are outdated?
npm outdated -g for npm, pnpm outdated -g for pnpm, uv tool list --outdated for uv, and brew outdated for Homebrew.
Should I upgrade everything at once?
Usually yes, but a major version can change how a tool behaves. Run brew outdated or npm outdated -g first, look for big version jumps, and use brew pin for Homebrew tools a project depends on.
How do I keep a tool on its current version?
For Homebrew, run brew pin with the formula name and brew unpin to release it. npm and pnpm have no pin command for global packages. Install the version you want, for example npm install -g typescript@5.4.5, and update other packages by name instead of running update -g. For uv, install the tool with a version specifier.
Can I update these without Terminal?
Yes, with an app that lists them. Greypaint's Tools page shows outdated Homebrew formulae and global npm, pnpm and uv packages, and updates each one when you click Update.
Last checked 13 October 2026 · Written by the makers of Greypaint
See what's out of date on your Mac.
Greypaint checks every app on your Mac and shows what needs an update. Try it free for 14 days.
$6.49 once after the trial · macOS 26 or later