Skip to content

Consider the workspaces below. The resulting hoisting will be something like this:

  • node_modules/react will have version 18, hoisted from packages/web
  • packages/mobile/node_modules/react can’t be hoisted and will have version 19
  • packages/mobile/node_modules/component-lib will be a symlink to packages/component-lib

But this tree is invalid: because the node_modules resolution algorithm always resolves symlinks before importing modules, the component-lib workspace will always require react in its version 18, even when accessed through mobile. This is despite mobile correctly providing the react dependency in version 19 through the peer dependency.

There is unfortunately no node_modules layout that can address that correctly.

{
"name": "component-lib",
"peerDependencies": {
"react": "*"
}
}
{
"dependencies": {
"component-lib": "workspace:*",
"react": "^18"
}
}
{
"dependencies": {
"component-lib": "workspace:*",
"react": "^19"
}
}