You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Yarn already supports this option. It makes it possible to work with tooling that expects certain modules to be located in inside the same package that consumes them.
Example
In order for a React Native app to build properly within a monorepo, some packages that react-native depends on must reside inside the node_modules folder within the app package. With yarn, I'm able to accomplish it with this configuration:
"workspaces": {
"packages": [
"api",
"app",
"shared/*"
],
"nohoist": [
// my-app is the name of the package inside the app folder"my-app/**"
]
}
Reacted by Anton Khitrenovich, roman, Luca Ban, Pierre Spring, Gjermund Garaba, Adrian Hesketh, Milan Raj, Jean-Baptiste M., Thee Sritabtim, Eric Crosson and 326 more
Reacted by Filipe Costa, Simon Sassi, Thomas Pischulski, Chanakya, Brady Holt, Andreas Korth, Robert Gruner, Dmitriy, rubixibuc, Guillaume and 77 more
Reacted by Maor Cohen, yonatanspery, Sunny Singh, Felix Salazar, Albert and kato-sst
What I'd prefer, rather than adding "nohoist" and having to manually configure it, is finding a way for nothing to hoist, so that each folder's node_modules directory only ever contained the dep graph that its own package.json would have produced.
Reacted by Franklin Davenport, Adrian Hesketh, Milan Raj, Kay Gosho, Zames Chua, Panagiotis Kapros, Max Liashuk, Kuroné Kito (黒音キト), will-fagerstrom, Barak Drechsler and 108 more
Reacted by Dan Dascalescu, Jimmy, Ferris Armstrong, Kim Daniel Engebretsen and yonatanspery
What I'd prefer, rather than adding "nohoist" and having to manually configure it, is finding a way for nothing to hoist, so that each folder's node_modules directory only ever contained the dep graph that its own package.json would have produced.
sounds very much likes "pnpm" approach of doing things.
At the very least, the canonical option should be hoist: false rather than nohoist: true to avoid the "notfalse" config antipattern. (Whatever direction we go, we can support nohoist as well.)
Some discussion around whether this should be per-workspace, or for the project as a whole.
Main hazard: can easily result in workspace projects that install fine in dev, but cannot be correctly used together in production. Eg, packages/foo has a peerDep on react@16.8.0 and packages/bar has a peerDep on react@16.13.0. Without hoisting, this conflict is not evident in development. As @ljharb points out, this is desired behavior for projects that provide separate connectors for different react versions, but definitely something that should be an opt-in.
Discussed other pnpm-style tree generation approaches, and/or having separate "tree strategy" settings for different workspaces. Eg, packages/foo uses global-style, packages/bar uses legacy-peer-deps, etc. (This would be a pretty significant refactor for arborist, but not impossible.) Decided that this is orthogonal to the question of whether we hoist to workspace parent dir or not.
Reacted by Forrest, Austin Ziegler and Alain Perkaz
I'd amend this to say, "hoisting" is the improper term in every case - that what is actually desired is control around "sharing".
I think by default, the root, and individual subpackages, should share all peer deps, and all subpackages themselves, but observably share nothing else (iow, it's fine if they actually share the same copy of lodash, but a workspace shouldn't be able to require lodash unless its own dep graph includes it).
Reacted by David Dostal, Daniel Friesen, JohnAL, Cody Ebberson, A. R. Dunster, easyTree, Bernard, Alan Szternberg and Dave
Hi guys is there any progress on this issue? I really want to use npm for workspaces but I can't because react-native projects require a nohoist option..
Reacted by Eric Crosson, zpeleg, Kaleb Pace, James, Chema, Mariusz Beltowski, Sunkey, Pierre Dommerc, zahbolla, Dominic Elm and 61 more
This would actually be very helpful for monorepos with Angular and certain dependencies that look for angular core and common as peer deps.
I'm encountering a scenario where I have an angular theme library that looks for angular/core and angular/common as a peer dep but it's getting hoisted to <project_root>/node_modules. Angular isn't because I have other packages that depend on a newer version of rxjs then angular.
Reacted by Guillaume, upfluentpatrickpilch, bertrandE, Attila DeLisle, Alexander Bulychev, Huston Hedinger, Ben Lesh, William Lahti and dsaves
I would also like to add my support for a nohoist option. I've ran into problems with eslint configurations in a monorepo because it expects to be installed at the local package level.
Reacted by Huaichao Wang, Alex V. Povar, Huston Hedinger, dsaves and Jacob Cable
I'd like to add an additional use case for being able to disable hoisting in workspaces. I recently had to abandon workspaces in favour of Lerna to resolve this for myself.
I am working on a very large project which has quite a few serevrless components to it. We have a bunch of queueing and lambada workers. The project is setup with the following folder structure
each of those folders is a npm package which maintains its own set of dependencies. Some shared some not, some packages that only exist in this project and wont be published to any registry.
Part of publishing an aws lambda is the package needs to contain all of the dependencies in a package (ignoring layers for now). What we want to be able to do is, after an install be able to zip up each of the lambdas with all and only their dependencies so the cdk deployment can pick that up and push it out too aws.
With hoisting everything is in the root which is many millions of unneeded files for each of the lambdas. Not only that, you must handle the folder structure of walking up the tree and pulling everything down to the lambda folder or you end up with a deeply nested folder structure in the lambda.
I was very close to creating some sort of symlink system of constructing the node_modules folder in each of the lambdas at deploy time, then zipping that up. But Lerna more or less just works
Reacted by Patrik Trefil, Jacob Page, DominicFarrington, Justin Trobec, David Dostal, Sindre Svendby, Lee Lovett, Jose Valerio, Matthew Mattheus, ryunsong-contentful and 6 more
Our use case is very similar to what @will-fagerstrom just described, with a twist of Lambda Layers.
We pack all 3rd party deps to the shared layer (as described here) and nohost all internal dependencies to the lambdas themselves. Currently it works perfectly with Yarn 1. Our workspaces config looks similar to the following:
If and when something like this lands, #375 is probably going to be the first step. If you have a moment, please go weigh in there about how this will affect your use case, if it will satisfy your needs, etc.
I will update that PR now with my notes from our discussion in the open RFC call a few days ago.
Thank you for pointing out the proposal in #375.
Unfortunately, I don't think it will help in the case I described above.
As you've mentioned in the proposal,
The wording of "nohoist" is overly specific to a particular
implementation. That is, the declaration describes the "what" of
package folder tree implementation, instead of the "why" of dependency
graph resolution semantics.
This is exactly the way we use nohost option in Yarn. It has nothing to do with the version resolution per se. Instead, we are dealing purely with the deduplication aspect of hoisting. The primary reason for that is the need to package individual parts of the project tree to be used outside - either individually (AWS Lambdas, as described by @will-fagerstrom) or in conjunction with other dependency resolution mechanisms (AWS Lambda + AWS Lambda Layers use case above).
Not fully tested, but if i specify typeRoots: {} with the needed types in my tsconfig.json of the specific package giving the errors, the compilation seems to succeed without errors. Might this be a way to circumvent conflicting @types dependencies?
Couldn't test it fully as i'm still building the project, but will update this post as i progress.
I have struggled with this issue for a while and eventually found a sort of workaround for a pretty specific case. This approach creates two separate node_modules folders containing dependencies ONLY for a particular sub-package, and then merges them, allowing you to deploy it - e.g. as a part of your CI pipeline.
Example:
cd my_monorepo_root
rm -rf ./node_modules
npm ci --install-links --ignore-scripts --workspace=azure-functions
cp -R ./node_modules ./packages/azure-functions
insane this still hasn't been added when so many people for four years now have been wanting it. Please!!
Reacted by wanghuaichao-pacvue, Štěpán Zavadil, zj-landeed, Abhijeet Singh, Vincent D'amour, Luis Daniel Rico Apaez, Michael Barney, Jr, Deimantas Jakovlevas, Peter Bakonyi, Nikhil Mehta and 61 more
So, any reply from the team ? This is a requirement for many of us sadly
Reacted by Jacob Cable, Jaka Maver, Radu Mardale, Deimantas Jakovlevas, Maximilian Beck, Dave Bauman, Abhijeet Singh, Alex Parloti, Matthew "G" Giacomazzo, Maor Cohen and 3 more
Totally support this option but found something that worked for me.
I'm using a monorepo to manage severless functions like other folks in the thread here, Digital Ocean specifically. The deployment process using their doctl CLI runs npm run build after npm install so I added a second install command scoped to the current directory:
Activity
ljharb commentedon Nov 11, 2020
What I'd prefer, rather than adding "nohoist" and having to manually configure it, is finding a way for nothing to hoist, so that each folder's
node_modulesdirectory only ever contained the dep graph that its own package.json would have produced.simllll commentedon Nov 19, 2020
sounds very much likes "pnpm" approach of doing things.
isaacs commentedon Dec 2, 2020
Current status:
hoist: falserather thannohoist: trueto avoid the "notfalse" config antipattern. (Whatever direction we go, we can supportnohoistas well.)packages/foohas a peerDep onreact@16.8.0andpackages/barhas a peerDep onreact@16.13.0. Without hoisting, this conflict is not evident in development. As @ljharb points out, this is desired behavior for projects that provide separate connectors for different react versions, but definitely something that should be an opt-in.packages/foousesglobal-style,packages/baruseslegacy-peer-deps, etc. (This would be a pretty significant refactor for arborist, but not impossible.) Decided that this is orthogonal to the question of whether we hoist to workspace parent dir or not.ljharb commentedon Dec 2, 2020
I'd amend this to say, "hoisting" is the improper term in every case - that what is actually desired is control around "sharing".
I think by default, the root, and individual subpackages, should share all peer deps, and all subpackages themselves, but observably share nothing else (iow, it's fine if they actually share the same copy of lodash, but a workspace shouldn't be able to require lodash unless its own dep graph includes it).
zameschua commentedon Jul 23, 2021
Hi guys is there any progress on this issue? I really want to use npm for workspaces but I can't because react-native projects require a nohoist option..
BitForger commentedon Oct 18, 2021
This would actually be very helpful for monorepos with Angular and certain dependencies that look for angular core and common as peer deps.
I'm encountering a scenario where I have an angular theme library that looks for angular/core and angular/common as a peer dep but it's getting hoisted to <project_root>/node_modules. Angular isn't because I have other packages that depend on a newer version of
rxjsthen angular.rmuchall commentedon Oct 22, 2021
I would also like to add my support for a nohoist option. I've ran into problems with eslint configurations in a monorepo because it expects to be installed at the local package level.
d3lm commentedon Oct 22, 2021
I agree. A
nohoistoption would be very useful.will-fagerstrom commentedon Nov 1, 2021
I'd like to add an additional use case for being able to disable hoisting in workspaces. I recently had to abandon workspaces in favour of Lerna to resolve this for myself.
I am working on a very large project which has quite a few serevrless components to it. We have a bunch of queueing and lambada workers. The project is setup with the following folder structure
each of those folders is a npm package which maintains its own set of dependencies. Some shared some not, some packages that only exist in this project and wont be published to any registry.
Part of publishing an aws lambda is the package needs to contain all of the dependencies in a package (ignoring layers for now). What we want to be able to do is, after an install be able to zip up each of the lambdas with all and only their dependencies so the cdk deployment can pick that up and push it out too aws.
With hoisting everything is in the root which is many millions of unneeded files for each of the lambdas. Not only that, you must handle the folder structure of walking up the tree and pulling everything down to the lambda folder or you end up with a deeply nested folder structure in the lambda.
I was very close to creating some sort of symlink system of constructing the
node_modulesfolder in each of the lambdas at deploy time, then zipping that up. But Lerna more or less just workskhitrenovich commentedon Nov 1, 2021
Our use case is very similar to what @will-fagerstrom just described, with a twist of Lambda Layers.
We pack all 3rd party deps to the shared layer (as described here) and
nohostall internal dependencies to the lambdas themselves. Currently it works perfectly with Yarn 1. Our workspaces config looks similar to the following:I would rather go back to NPM than to Yarn 2+.
isaacs commentedon Nov 5, 2021
If and when something like this lands, #375 is probably going to be the first step. If you have a moment, please go weigh in there about how this will affect your use case, if it will satisfy your needs, etc.
I will update that PR now with my notes from our discussion in the open RFC call a few days ago.
isaacs commentedon Nov 5, 2021
#375 (comment)
khitrenovich commentedon Nov 5, 2021
@isaacs -
Thank you for pointing out the proposal in #375.
Unfortunately, I don't think it will help in the case I described above.
As you've mentioned in the proposal,
This is exactly the way we use
nohostoption in Yarn. It has nothing to do with the version resolution per se. Instead, we are dealing purely with the deduplication aspect of hoisting. The primary reason for that is the need to package individual parts of the project tree to be used outside - either individually (AWS Lambdas, as described by @will-fagerstrom) or in conjunction with other dependency resolution mechanisms (AWS Lambda + AWS Lambda Layers use case above).49 remaining items
maahtiin commentedon Jan 8, 2024
Not fully tested, but if i specify
typeRoots: {}with the needed types in mytsconfig.jsonof the specific package giving the errors, the compilation seems to succeed without errors. Might this be a way to circumvent conflicting@typesdependencies?Couldn't test it fully as i'm still building the project, but will update this post as i progress.
ranwawa commentedon Jan 8, 2024
Merged PR 9846: Add deployment pipeline
raisiqueira commentedon Apr 17, 2024
Hey folks, what's the status on this? Will it ever happen?
ranwawa commentedon Apr 17, 2024
Ditch npm workspaces
sweetpalma commentedon Aug 12, 2024
I have struggled with this issue for a while and eventually found a sort of workaround for a pretty specific case. This approach creates two separate
node_modulesfolders containing dependencies ONLY for a particular sub-package, and then merges them, allowing you to deploy it - e.g. as a part of your CI pipeline.Example:
cd my_monorepo_root rm -rf ./node_modules npm ci --install-links --ignore-scripts --workspace=azure-functions cp -R ./node_modules ./packages/azure-functionsranwawa commentedon Aug 12, 2024
zreecespieces commentedon Jan 20, 2025
insane this still hasn't been added when so many people for four years now have been wanting it. Please!!
mbret commentedon Jun 1, 2025
So, any reply from the team ? This is a requirement for many of us sadly
gidich commentedon Sep 29, 2025
Bumping this issue - looking for using this as well.
ranwawa commentedon Sep 29, 2025
joshcanhelp commentedon Oct 17, 2025
Totally support this option but found something that worked for me.
I'm using a monorepo to manage severless functions like other folks in the thread here, Digital Ocean specifically. The deployment process using their
doctlCLI runsnpm run buildafternpm installso I added a second install command scoped to the current directory:{ "scripts": { "build": "npm --prefix=. install && tsc" }, "dependencies": { "slonik": "^47.3.2" } }ranwawa commentedon Oct 17, 2025
build: change the package manager from npm to pnpm