berry icon indicating copy to clipboard operation
berry copied to clipboard

[Feature] Injected Workspace Dependency Installs

Open sohcah opened this issue 2 months ago • 2 comments

  • [ ] I'd be willing to implement this feature (contributing guide)
  • [ ] This feature is important to have in this repository; a contrib plugin wouldn't do

Describe the user story

When working in a large workspace, Peer Dependencies don't currently work particularly conveniently. For example, if I have the following structure:

  • @my-project/ui with a peer dependency on "react": "^18.0.0 || ^19.0.0", and a dev dependency on "react": "18.2.0"
  • @my-project/app with a dependency on @my-project/ui and on "react": "19.0.0"
  • @my-project/web with a dependency on @my-project/ui and on "react": "18.2.0"

Then any code within @my-project/ui will reference the Dev Dependency [email protected] even when referenced from the /app project which uses [email protected]. With a regular npm: or a file: dependency, it would resolve correctly to the [email protected] peer dependency.

This may be better explained by Rush's "Injected dependencies" documentation here.

Describe the solution you'd like

2 primary aspects to this:

  • An "Injected" option for installing a workspace: dependency, by coping the files rather than symlinking - so devDependencies aren't installed - similar to how the link:protocol works.
  • A yarn reinject [package] command which re-copies the files for all Injections of a specific package (or all packages if package is not specified).

Describe the drawbacks of your solution

The most likely drawback with this solution is the requirement to re-run a synchronisation script after building sub-projects - in the PNPM case, the sync command is often setup to automatically run through Monorepo tools (e.g. Rush or Turborepo).

Describe alternatives you've considered

The most obvious alternative here, which is what I'm currently using projects, is to just use the existing file: dependency protocol to reference workspace dependencies, but this loses many of the nice Workspaces features that yarn and monorepo tools provide, and re-synchronising after a change requires a full yarn install which takes a significant amount of time. Additionally, this means that the yarn.lock hash changes with any changes in that dependency.

sohcah avatar Oct 18 '25 14:10 sohcah

Then any code within @my-project/ui will reference the Dev Dependency [email protected] even when referenced from the /app project which uses [email protected]. With a regular npm: or a file: dependency, it would resolve correctly to the [email protected] peer dependency.

No, that's only the case if you use the node_modules or pnpm linkers, which have this inherent limitation due to their reliance on the filesystem. The default pnp linker doesn't have that and always resolves peer dependencies right.

As you mention pnpm supports making copies of workspaces to mitigate this issue, but it feels more than a little clunky to me (not that they really have a much better choice, but I think we do).

arcanis avatar Oct 18 '25 14:10 arcanis

Thanks for the clarification there! Unfortunately, using pnp (or until very recently even pnpm) linking still isn't an option as far as I'm aware for React Native / Expo development. :( Definitely agreed that it's clunky - but IMO a significantly less messy solution that using file: dependencies.

sohcah avatar Oct 18 '25 14:10 sohcah