Closed karlhorky closed 2 weeks ago
After doing a bit of research in the Homebrew repository, I can see the following:
--without-corepack
flag in the node.rb
Formula
brew install corepack
(which would mean the version number is managed by Homebrew). An exception is made for old versions such as node@20
, node@18
, etc, where the --without-corepack
is not present
node@22
: corepack
not installednode@20
and older: corepack
installed--without-corepack
flag was first added in a PR for Node.js 17.3.0, involved Homebrew members @chenrui333 @carlocab @SMillerDev @bevanjkay
I originally reported this over in the Node.js repository:
And received a response that this should be reported here.
Hey Homebrew maintainers (@carlocab @SMillerDev @bevanjkay @chenrui333 @cho-m), I'm Claudio, one of the core collaborators of Node.js, I'm chiming in here as I've never noticed that Homebrew intentionally removed core features from Node.js (https://github.com/Homebrew/homebrew-core/blob/master/Formula/n/node.rb#L69-L70) on its formulae.
This is not a sanctioned way that we (Node.js) approve of people distributing Node.js. This might cause many expectation issues and hinder how we expect community package managers to ship Node.
So, I'd like to ask Homebrew maintainers to remove those flags formally. Node.js users expect all installation methods bundled via Node.js version managers, OS package managers, or community package managers to install Node similarly.
We cannot endorse Homebrew as a way of installing Node.js if Homebrew intentionally changes (without the user's explicit consent and knowledge) what gets shipped when they install Node. (Note that this is not a threat, although it might sound; We just want to ensure that the official ways we recommend on our website all have the same behaviour)
~Even worse, Homebrew is deliberately changing which npm
version gets installed with the Node.js formula, which should always contain the npm version that comes with the respective Node.js binary. Otherwise, it is incorrect to advertise to the end-user that a specific version of Node.js is being installed when certain components are being modified. This also violates our LICENSE, as you are distributing Node.js in a way that sounds and looks like it is binary but changes the result. On a separate note, I can understand why these args are being passed, but anything else is definitely, let's say "not cool".~
I'd certainly appreciate it if this behavior is undone.
Edit: My side assumed that different versions are shipped, which is incorrect. However, Homebrew is still discouraged from manually bundling npmin an extraneous way.
Edit 2: It is important to mention that my statements are not a representation of Node.js as a whole but as someone who is deeply involved with its infrastructure and development.
I've made a PR here: https://github.com/Homebrew/homebrew-core/pull/194041 but no idea yet if it passes, if the changes are correct; I'll test on my MacBook later :)
Even worse, Homebrew is deliberately changing which
npm
version gets installed with the Node.js formula
That's not actually accurate -- we always make sure that the npm
version matches what's shipped with Node:
If there's been a mismatch historically then that was an oversight.
That's not actually accurate -- we always make sure that the npm version matches what's shipped with Node:
Appreciate for chiming in. I raised a question within my PR OOC to better understand Homebrew's deliberate decision here; Apologies for my lack of context here 🙇
This also violates our LICENSE, as you are distributing Node.js in a way that sounds and looks like it is binary but changes the result.
This is quite an alarming sentence to deliver to send to downstreams and implies NodeJS has a very strong stance against https://opensource.org/osd.
Focussing on the pull request in isolation: I'm ok with making changes. The corepack decision came at a time where corepack was still experimental several years ago (and the corepack
build flags didn't actually exist yet). I recognise things have changed - it's simply been that nobody has raised the question since, perhaps in part because the % of users that install corepack is very low.
Node 23 is in a couple days and is an excellent opportunity to make any big changes along with a fresh node@22
.
npm
was actually done in response to upstream reported issues: npm/npm#3794. The default npm build within Node didn't work properly under Homebrew so we needed to build it separately for it to work. It's possible things have improved since - I'll need to figure out what the test case for that is as 10 years is a long time. Note that we have for years guaranteed that we will always match upstream versions (unless there's some critical bugfix but that hasn't been the case for many years). I do however agree that using the bundled version is nicer if it works better nowadays.
But I'm overall OK for removing --without-corepack
(but only if we delete the separate corepack
formula too and merge it in).
Node.js users expect all installation methods bundled via Node.js version managers, OS package managers, or community package managers to install Node the same way.
Based on quick check through Repology, this statement doesn't seem to hold up:
npm
- https://ports.macports.org/port/npm10/corepack
never merged - https://github.com/macports/macports-ports/pull/16615This also violates our LICENSE, as you are distributing Node.js in a way that sounds and looks like it is binary but changes the result.
This is quite an alarming sentence to deliver to send to downstreams and implies NodeJS has a very strong stance against opensource.org/osd.
Yes, agreed. I'll also note that a number of packages mentioned in upstream documentation do some pretty similar things as we do:
--without-corepack
: https://src.fedoraproject.org/rpms/nodejs22/blob/03812ccd222c2c7ffbc3721ef11dd2d45e2f0e73/f/nodejs22.spec#_591--without-npm
and --without-corepack
: https://salsa.debian.org/js-team/nodejs/-/blob/94873a3915ac88b3f423c44a44e90db939a151ad/debian/rules#L26--without-npm
: https://gitlab.archlinux.org/archlinux/packaging/packages/nodejs/-/blob/a2f9410569ec3621fc8fbe655a8ee0e479d2c6a5/PKGBUILD#L53Are any/all of these in violation of Node's license?
Edit: Got scooped by @cho-m. Didn't see the previous comment till I submitted mine 😄
But I'm overall OK for removing
--without-corepack
(but only if we delete the separatecorepack
formula too and merge it in).
Might be tricky for some dependents to both depend on node
but conflict with node
:
This is quite an alarming sentence to deliver to send to downstreams and implies NodeJS has a very strong stance against opensource.org/osd.
Apologies, this is indeed an unwarranted statement from my side. As per https://github.com/nodejs/node/blob/main/LICENSE, I don't think any license is actually being breached.
The corepack decision came at a time where corepack was still experimental several years ago (and the corepack build flags didn't actually exist yet). I recognise things have changed - it's simply been that nobody has raised the question since, perhaps in part because the % of users that install corepack is very low.
I understand that, but there are active conversations within the Node team about whether corepack should be removed or not; removing it from Homebrew install paths at this time is not recommended.
Based on quick check through Repology, this statement doesn't seem to hold up:
Debian (disable both1). Separate packages that track latest versions for:
- Fedora (disable corepack2)
Alpine (disable npm3) - Separate package that track latest version for:
Arch Linux (disable npm4). Separate package that track latest version for:
MacPorts (disable npm5, don't install corepack in files6). Separate package that track latest version for:
- npm - ports.macports.org/port/npm10
- NOTE: corepack - never merged PR - corepack: new Portfile macports/macports-ports#16615
I doubt that the we are aware that this was the case. We don't have control over what package managers decide to do or not with Node, hence I'm reaching out here. I appreciate you for compiling this list, I'm actually shocked that this is the case, and I'm not sure if the Node.js release team is aware of this -- I'll reach them out and check-in.
npm was actually done in response to upstream reported issues: https://github.com/npm/npm/issues/3794. The default npm build within Node didn't work properly under Homebrew so we needed to build it separately for it to work.
I imagined something like this was the case 🤔
I'll need to figure out what the test case for that is as 10 years is a long time.
I don't want to waste your volunteering time unnecessarily. I would appreciate it if you could check that, but only if that's a reasonable ask from my side.
Node 23 is in a couple days and is an excellent opportunity to make any big changes along with a fresh node@22.
Node 23 got delayed a bit, I can check back what is the updated timeline, the irony is that we're facing issues specifically with macOS (https://github.com/nodejs/Release/issues/1034)
Might be tricky for some dependents to both depend on
node
but conflict withnode
:
I think the corepack
build in Node skips shipping yarn
etc binaries so should be OK I think. Should of course double check before shipping to ensure only the corepack
binary is installed.
Apologies, this is indeed an unwarranted statement from my side. As per nodejs/node@main/LICENSE, I don't think any license is actually being breached.
Apologies again for the unnecessary and inaccurate statement (regarding LICENSE violations) -- to clarify, my intent here was to refer as the official binaries of Node.js and untethered modifications on them; But this is not applicable (nor actually part of the LICENSE of Node) here as Node is built from source by Homebrew.
Node 23 is in a couple days and is an excellent opportunity to make any big changes along with a fresh node@22.
Node 23 got delayed a bit, I can check back what is the updated timeline, the irony is that we're facing issues specifically with macOS (nodejs/Release#1034)
I linked the wrong issue, https://github.com/nodejs/node/issues/55181
This is not a sanctioned way that we (Node.js) approve of people distributing Node.js.
AFAIK this is not correct, we (Node.js) maintain the ./configure
flags that enable and disable certain features, precisely so folks can build a version of Node.js that fit their use case. I also don't think we need to approve distributing Node.js, it's an open-source software.
The part on user expectations still holds though, but I think we can only complain as Homebrew users, not as Node.js maintainers.
I doubt that the we are aware that this was the case. We don't have control over what package managers decide to do or not with Node, hence I'm reaching out here. I appreciate you for compiling this list, I'm actually shocked that this is the case, and I'm not sure if the Node.js release team is aware of this -- I'll reach them out and check-in.
We are certainly aware, AFAICT it's always been a quite transparent process.
The part on user expectations still holds though, but I think we can only complain as Homebrew users, not as Node.js maintainers.
Indeed, concur here.
AFAIK this is not correct, we (Node.js) maintain the ./configure flags that enable and disable certain features, precisely so folks can build a version of Node.js that fit their use case. I also don't think we need to approve distributing Node.js, it's an open-source software.
I partially agree here, but I cannot speak as for Node as a whole, and your statements (as a TSC member) will supersede mine.
(Referring to the part of community package managers changing what is bundled or not with default "nodejs" distributions -- I would understand if this was a bottle of brew install node --without-corepack
(and same for Debian, and others) -- but that is just my expectation)
We are certainly aware, AFAICT it's always been a quite transparent process.
Then this is possibly a me issue. Was there any documentation regarding which OS managers/package managers are deviating from the default "ship" (?)
Suppose this is a well-known knowledge (which I unfortunately was unaware of). In that case, we do need to update the Node.js website to reflect that these package managers diverge from other installation methods. Which, in my opinion, is still a breakage of consistency.
Since @aduh95 has chimed in, I'll defer his opinions as what would be a relay of Node.js will here; If he believes this is completely fine for Homebrew to do, then I believe Homebrew will not need to remove the --without-corepack
flag, and I'll proceed with proposing changes internally on our website so that these installation methods have explicit mentions that they might not come with these features.
Having that said, it is hard for me (as someone contributing to Node's infra and website) to keep track of what other managers are doing or not and I could only assume and wish that they'd distribute Node as close as possible from pristine.
My opinion (and does not necessarily represent the TSC's, or any other group I'm a part of, and is obviously not legal advice) is that Homebrew is in no "obligation" to follow the same conventions as the upstream project when it comes to distribution. As I said above, IMO it's certainly fine for Homebrew users to request changes, and IMO it's perfectly fine to have Homebrew maintainers being the ultimate judges.
As a user, I agree that aligning with Node.js defaults seems to be the least likely to cause confusion.
I'm certainly not qualified to decide Node.js will, and everyone is welcome to disagree with my position.
My opinion (and does not necessarily represent the TSC's, or any other group I'm a part of, and is obviously not legal advice) is that Homebrew is in no "obligation" to follow the same conventions as the upstream project when it comes to distribution.
As I said above, IMO it's certainly fine for Homebrew users to request changes, and IMO it's perfectly fine to have Homebrew maintainers being the ultimate judges.
As a user, I agree that aligning with Node.js defaults seems to be the least likely to cause confusion.
I'm certainly not qualified to decide Node.js will, and everyone is welcome to disagree with my position.
I appreciate your words here, couldn't have spoken better, in full agreement here.
Hello all. I'm a member of Homebrew's Project Leadership Committee. You've also heard from @Bo98 who is on our TSC. We try to ship binaries as close to upstream as possible, as long as it makes sense for us to do so. As other maintainers have mentioned, we are operating in the same way we have for a decade or longer. We're happy to make formula changes if it helps our users, but we will not make sudden changes that may disrupt large amounts of users. We're happy to discuss with Node's maintainers if there is upstream concern, otherwise we will continue to package and ship as we always have.
@ovflowd Claims of OSS license violations are something we take very seriously. Please ensure your facts are in order before opening an issue and making claims are incorrect and alarmist.
@aduh95 Thank you for chiming in from the Node side. We will discuss internally on how we should handle corepack
for Node 23.
We're happy to make formula changes if it helps our users, but we will not make sudden changes that may disrupt large amounts of users. We're happy to discuss with Node's maintainers if there is upstream concern, otherwise we will continue to package and ship as we always have.
There are concerns that we would like to have it shipped as close upstream as possible, which is not precisely the case right now. But at the same time, you decide to decide what to ship.
@ovflowd Claims of OSS license violations are something we take very seriously. Please ensure your facts are in order before opening an issue and making claims are incorrect and alarmist.
I already apologised for my unnecessary escalation here; it was wrong, excessive, and mostly done as an initially rushed and concerned act from my side. I was shocked that Homebrew was doing something differently, failing to realise this was the status quo. Still, it was factually incorrect and wrong; apologies for that. I have a terrible habit of jumping, and sometimes, I forget to think for 2 seconds about whether I should write something or not.
Now we have corepack
bundled with node
formula.
should be good now, closing the issue.
🎉
I'm a bit confused by this change.
As I understand, there are plans for corepack to be separated from the Node release in favor of a standalone installation (https://github.com/nodejs/package-maintenance/pull/606/files). When that happens, will the corepack
formula be reintroduced?
I've been installing corepack via Homebrew in anticipation of this change, but now it's been removed. For context, I preferred using Homebrew over npm for installing corepack because I switch between multiple Node/npm versions with nvm.
I wonder if it could've been possible to keep the corepack
formula as-is for standalone installation?
We're opting for consistency among our formulae right now. When Node makes whatever changes they plan to make, we will adapt accordingly. They may involve bringing the corepack
formula back, but we will address that when necessary.
I agree that including corepack
with node
for consistency makes sense.
But Corepack also supports independent installation, so being consistent with that option seems important as well: https://github.com/nodejs/corepack#manual-installs
Could we consider reintroducing the standalone corepack
formula as an option for these users? This seems like a flexible solution that upholds consistency while accommodating broader use cases.
following up on @carlocab 's comment about complications for users of yarn/pnpm formulae what would be the preferred resolution there because this change made the node formula incompatible with yarn/pnpm formulae
yarn/pnpm formulae don't depend on the node formula (beyond build and test phases), but they do require node to be installed, which most of us, and especially because of the bundled notice, would install via brew install node
but node and yarn/pnpm formulae cannot coexist right now. Ping @zkochan
If I may add a personal 2c on this
Following the thread, I do not understand what made the homebrew maintainers go along with this, as the net benefit from a user perspective is simply skipping "brew install corepack" (IF you actually need corepack features), while actually losing the ability to decide how to make yarn/pnpm available - via corepack or via specific homebrew formulae.
@andreineculau Thank you for this additional info. We definitely did not intend to cause issues with yarn/pnpm. We are discussing internally and will have a path forward soon.
FWIW on nixpkgs, there's a nodejs
package and a nodejs-slim
package, maybe it's something that would also benefit Homebrew.
Following the thread, I do not understand what made the homebrew maintainers go along with this
It was somewhat a request from upstream to "conform" with the expectations Node has for distributing Node. (Note that we defer the decisions of how Homebrew distributes Node to Homebrew, but at least speaking for myself, It is a desirable expectation for the formulae to be as close as possible of upstream)
Corepack might or might not be removed in the future; I like the idea of a node-slim formulae, but not sure how much of a hassle it would be for Homebrew maintainers.
I also can't see how corepack being installed (it is not enabled by default) would cause any issues for the yarn/pnpm formulae's 🤨 -- this was the behaviour until Node.js v20 on Homebrew, so either the issue existed before or is it a new one, or maybe particular to your system? 👀
Also my 2cents, I don't think it is productive to argue what Node is supposed to be or not on a thread on Homebrew core, if you believe Node is doing too much, you're more than welcome to provide feedback upstream. (Apologies if I am overreaching here)
this change made the node formula incompatible with yarn/pnpm formulae
Can you clarify, with steps to reproduce, what broke here? The original corepack
formula already had a dependency on node
so the install footprint before and after should be similar (except the yarn/pnpm
shims are now opt-in via corepack enable
).
The footprint of the original corepack
formula was:
/opt/homebrew/
-> bin/
-> corepack
-> pnpm
-> pnpx
-> yarn
-> yarnpkg
(everything else was hidden in /opt/homebrew/opt/corepack/libexec as internal details)
plus everything installed by node
as it was a required runtime dependency.
Now the footprint is:
/opt/homebrew/
-> bin/
-> corepack
-> lib/
-> node_modules/
-> corepack/
-> (contents of corepack package)
plus everything installed by node
as before. pnpm/pnpx/yarn/yarnpkg
can be returned to their original location via corepack enable
.
One difference I do see is the original corepack
formula was constructed like:
#!/opt/homebrew/opt/node/bin/node
process.env.COREPACK_ENABLE_DOWNLOAD_PROMPT??='0';
require('./lib/corepack.cjs').runMain(process.argv.slice(2));
but the newer one has #!/usr/bin/env node
. Is that the issue you're seeing? We can probably fix that if so.
Bo, I have been collecting root-cause data since the last comment, and can nuance the "this change made the node formula incompatible with yarn/pnpm formulae":
Overall one can consider these edge/corner cases, but ultimately corepack's shim functionality (with no guards) coupled with poor practices (assumptions about the environment) make the pure availability of corepack a problem in itself.
One could say that this (not removing corepack from the node formula, and pushing for better practices) is the right thing long term, but it could have benefitted from more consideration about implications and gains (homebrew users skipping brew install corepack
if needed).
Off-topic: the shebang discovery probably makes sense to enforce running with homebrew's node
in other scenarios, pnpm is installed via older/custom formulae which specify conflicts_with corepack
In terms of older formulae: this is something we can never realistically support. If you're mixing and matching packages from different points in time there's a very high chance things will break. Node dependents that don't link to anything native have it a bit easier - it would be significantly worse if you mixed things like a dylib that breaks ABI often.
In terms of custom formulae, conflicts_with
in general does suck. The mistake here was probably ever shipping corepack
with the shims pre-linked. We actively try to reduce conflicts_with
rather than keep them.
We kept the brew install corepack
alias as a consideration to break less people - i.e. so CI scripts that do it do not break. How it also affects conflicts_with
is unfortunate, though not one I would've anticipated would have affected many. I can't find any public tap on GitHub that does it that's not a homebrew-core fork or got "test" in its name: https://github.com/search?q=%22conflicts_with+%5C%22corepack%5C%22%22+NOT+is%3Afork+&type=code&p=1, but acknowledge there could be some low-volume ones (or private ones) that haven't been indexed.
The other two scenarios make more sense and do sympathise with scripts breaking as we do try to avoid that. I do have one question about them though: how do they handle Linux distros? Homebrew's permission model is more lax but if I did corepack enable
on Ubuntu 24.10 I get:
$ sudo apt install node-corepack
$ corepack enable
Internal Error: EACCES: permission denied, symlink '../share/nodejs/corepack/dist/pnpm.js' -> '/usr/bin/pnpm'
It would perhaps make some sense if Homebrew was able to similarly block corepack enable
without an explicit --install-directory
(or default it to something else you need to add to your PATH) so that it's not destructive by default.
Unfortunately, I'm not sure if a perfect solution exists without potentially some changes upstream but we'll try our best to try cover the majority.
brew gist-logs <formula>
link ORbrew config
ANDbrew doctor
outputVerification
brew doctor
output saysYour system is ready to brew.
and am still able to reproduce my issue.brew update
and am still able to reproduce my issue.brew doctor
and that did not fix my problem.What were you trying to do (and why)?
I was trying to use Homebrew to install Node.js v22 and use Corepack, in the same way that I installed Node.js v20 and used Corepack
What happened (include all command output)?
Following the official Node.js download page, I used Homebrew to install
node@22
, and then tried to enable thecorepack
binary as in the Node.js docs and it is not available:This is divergent behavior from
node@20
(and other versions), where installation yields a working, installed Corepack out of the box:What did you expect to happen?
node@22
should install the Corepack binary likenode@20
does (Corepack is expected to be a part of Node.js)Step-by-step reproduction instructions (by running
brew
commands)