Safeguard
Developer Tools•

What does brew pin do, and does it stop a package updating?

brew pin stops brew upgrade from changing a package, but dependencies can break and self-updating casks can still change. Know the tradeoff before pinning.

Safeguard Security Team
3 min read

brew pin stops a formula from being upgraded when you run brew upgrade. It does not stop everything: the Homebrew manual warns that packages depending on newer versions of a pinned formula may fail, and that pinned casks with auto_updates true may update themselves outside Homebrew. Use pins sparingly and keep a review date.

What the manual says

From the Homebrew manual page:

  • pin: prevents the specified package from being upgraded when issuing brew upgrade.
  • unpin: allows it to be upgraded again.
  • upgrade: upgrades outdated, unpinned packages. If you name a package, it upgrades only that, unless it is pinned.

The manual also warns that other packages which depend on newer versions of a pinned formula might not install or run correctly. And pinned casks with auto_updates true may update themselves outside Homebrew.

Where pinning helps

Pinning is a temporary tool for a specific problem: a newer version of a compiler, database client or CLI breaks your workflow and you need time to fix it. Pin, work around, then unpin.

brew pin postgresql@16
brew unpin postgresql@16

Where it hurts security

A pin freezes a patch level. If the pinned package has a security fix in a newer release, brew upgrade will not apply it. That is the exact situation patch management exists to prevent, so a pin is a risk acceptance, not a neutral setting.

The dependency warning cuts the other way too. A pinned formula can block upgrades of others that need its newer version, leaving a half-updated machine.

Casks that update themselves

Many GUI applications update through their own mechanism. The manual's note about auto_updates true means the cask can change without Homebrew involved, so a pin does not guarantee a stable version. If you need strict control, check the application's own update settings too, such as those covered in how to control VS Code updates across a team.

A sensible policy for developer laptops

CaseAction
Routine toolsUpgrade weekly, no pins
A tool that broke on a new releasePin with a ticket and a review date
Team needs identical versionsUse a versioned toolchain per project, not Homebrew pins
Self-updating appControl through the app's own policy

Keep a list of pins

Run brew list with the pinned filter occasionally, or record pins in your setup script, so they do not outlive their reason. A pin from last year is a forgotten decision.

Safeguard's asset discovery and dependency scanning help you see versions across projects, which is the visibility a pin tends to hide. Try a free scan at gold.safeguard.sh/scan.

Common mistakes

People pin to fix a one-off problem and then never unpin. Others pin a library without noticing it holds back tools that depend on a newer one. A third assumes a pin covers a self-updating app. Write each pin down with a reason and a date in your setup notes, and review the list when you review other exceptions.

Quick check

Does brew upgrade skip pinned formulae?

Yes. The manual says upgrade handles outdated, unpinned packages, and a named package is skipped if pinned.

Can a pinned cask still change?

Yes, if it has auto_updates true it may update itself outside Homebrew, per the manual.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.