Why linking keg-only formulae requires --force option in homebrew?

Background knowledge: I installed node when installing yarn via brew before, but yarn doesn’t use the latest version of node well so I’m trying to switch to past version of node now.

Note: node@8 seems to be a keg-only formula

Why do the homebrew developers decide to prevent us from using

brew link node@8

and ask us to use

brew link --force node@8

In other words, what’s so special about keg-only formula, that makes the developers decide to ask users to add --force option to link them?

There are different reason for a formula to be keg-only. In your case we already have node taking /usr/local/bin/node. Typical solution would be adding /usr/local/opt/node@8/bin to your $PATH.

Yes, thank you fro the explanations.

Is there a reason why we need the --force command? non-keg-only package don’t need --force option, so why does keg-only packages need it?

1 Like

Because formulae are deemed keg-only if they overwrite an existing command.

1 Like

Thank you for the reply.

I’m unclear about how homebrew knows a package will know when a package is going to overwrite an existing command.

As an example, I did these before (which ultimately leads me to ask this question):

brew install node
brew install node@8
brew unlink node
brew link node@8

Why does the last command need --force? I already unlink node so node@8 shouldn’t be clashing with node now. In other words, overwriting shouldn’t be happening.

It knows because people defined it as such, afaik there’s no actual check. There’s just the formula defining that node@8 will clash with an existing binary, if that binary is currently linked is irrelevant. It could still be in the path one way or another.

Is there a reason the last command need --force? I already unlink node so node@8 shouldn’t be clashing with node now. In other words, overwriting shouldn’t be happening.

There is also another option --overwrite for brew link. You mentioned --overwrite before, from a literal perspective, one would assume it is related to --overwrite option, but we are talking about the --force option here.

I am a little bit confused about the difference between them, can you please elaborate on their difference?

Clashing is only one reason. For example, in the case of OpenSSL, there is no clashing of anything in /usr/local/bin/ or what, but it will shadow the OpenSSL coming with macOS. There can be many other reasons, so it is impossible to detect whether linking would cause trouble. The --force simply transfers the responsibility of detection from Homebrew to user. So no, --force doesn’t mean that it will clash. It means “think twice”.

If user is responsible for thinking, what should the user think?

What’s the many other reasons the user need to consider?

Below commands worked for me.

brew install node
brew install node@10
brew unlink node
brew link --force --overwrite node@10

1 Like

Same for me.
To go back from current node (12.x) to node@10 I had to.
brew install node @10
brew unlink node
brew link --force --overwrite node@10

neither brew link --force node@10 nor brew link --overwrite node@10 did the trick by themselves.

Any idea why?