{"id":17919264,"url":"https://github.com/mbeaudru/yarn-workspaces-peerdeps-resolution","last_synced_at":"2026-05-09T16:05:10.566Z","repository":{"id":111003576,"uuid":"164605784","full_name":"mbeaudru/yarn-workspaces-peerdeps-resolution","owner":"mbeaudru","description":"A reproduction for an issue we encountered in trying to work between a workspace and other repositories.","archived":false,"fork":false,"pushed_at":"2019-01-08T08:53:24.000Z","size":6,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-14T17:18:23.624Z","etag":null,"topics":["peerdependencies","workspaces","yarn"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mbeaudru.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-01-08T08:51:38.000Z","updated_at":"2023-03-10T09:53:20.000Z","dependencies_parsed_at":null,"dependency_job_id":"9035ae01-af36-4834-b4d2-3bc475a1039d","html_url":"https://github.com/mbeaudru/yarn-workspaces-peerdeps-resolution","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mbeaudru/yarn-workspaces-peerdeps-resolution","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mbeaudru%2Fyarn-workspaces-peerdeps-resolution","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mbeaudru%2Fyarn-workspaces-peerdeps-resolution/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mbeaudru%2Fyarn-workspaces-peerdeps-resolution/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mbeaudru%2Fyarn-workspaces-peerdeps-resolution/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mbeaudru","download_url":"https://codeload.github.com/mbeaudru/yarn-workspaces-peerdeps-resolution/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mbeaudru%2Fyarn-workspaces-peerdeps-resolution/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279020078,"owners_count":26086806,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["peerdependencies","workspaces","yarn"],"created_at":"2024-10-28T20:15:42.210Z","updated_at":"2025-10-14T17:18:24.398Z","avatar_url":"https://github.com/mbeaudru.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Working between yarn workspaces and other projects with peerDependencies\n\nThis repository is a meant to reproduce an issue we encountered in trying to work between a workspace and other repositories.\n\nTo be concrete, we have workspaces for components (more or less smart) and tooling separated in multiple packages, but \"projects\" are separate repositories and depends on packages from the workspace.\n\n\u003e **Note :** We have created a npm package \"log-version\" that only *console.log* its current package version to demonstrate the  issue.\n\n## The issue\n\nWe want to be able to dev on *package-a* while it is linked in *project-a* and always have the same results than in prod, when packages are taken from the registry for instance.\n\n- *package-a* belongs to the workspace and has a **peerDependency** on **log-version ^1.0.0**\n- *package-b* and *package-c* belongs to the workspace and both have a dependency on **log-version@1.0.0**\n\n\u003e This makes log-version@1.0.0 be hoisted by the workspace\n\n- *project-a* has a **dependency** on **log-version@1.1.0** and on *package-a* (version doesn't matter)\n\n```\nworkspaces\n  |-- node_modules\n    |-- log-version@1.0.0\n  |-- packages\n    |-- package-a (peerDependency: log-version ^1.0.0)\n    |-- package-b (dependency: log-version@1.0.0)\n    |-- package-c (dependency: log-version@1.0.0)\n\nproject-a\n  |-- node_modules\n    |-- log-version@1.1.0\n    |-- package-a\n  package.json\n    * dependency:\n      - log-version@1.1.0\n      - package-a\n```\n\n### In dev\n\nWe link *package-a* in *project-a* and run *project-a*:\n\n- *project-a* has **log-version@1.1.0** in dependency so uses version **1.1.0** when running\n- *package-a* has **log-version ^1.0.0** in *peerDependency* so running in *project-a*, should use **log-version@1.1.0**\n\n**BUT**, *package-a* in fact uses **log-version@1.0.0** because it is found in the workspaces root *node_modules* before!\n\nFollow the steps, having in mind that *package-a* is linked into *project-a*:\n\n```\nworkspaces\n  |-- node_modules // STEP 3\n    |-- log-version@1.0.0 // STEP 4\n  |-- packages\n    |-- package-a (peerDependency: log-version ^1.0.0) // STEP 2\n    |-- package-b (dependency: log-version@1.0.0)\n    |-- package-c (dependency: log-version@1.0.0)\n\nproject-a\n  |-- node_modules\n    |-- log-version@1.1.0\n    |-- package-a // STEP 1\n  package.json\n    * dependency:\n      - log-version@1.1.0\n      - package-a\n```\n\n### In production\n\n- *project-a* has **log-version@1.1.0** in dependency so uses version **1.1.0** when running\n- *package-a* has **log-version ^1.0.0** in *peerDependency* so running in *project-a*, uses **log-version@1.1.0**\n\nWhen not linked, we do have:\n\n```\nproject-a\n  |-- node_modules\n    |-- log-version@1.1.0 // STEP 2\n    |-- package-a // STEP 1\n  package.json\n    * dependency:\n      - log-version@1.1.0\n      - package-a\n```\n\n## Steps to reproduce\n\n- clone the repository\n- at repository root, run `yarn prepare` to install all dependencies\n- at repository root, run `yarn start` to run *project-a*\n\nObserve that despite being in peerDependency, log-version is used both @1.1.0 and @1.0.0\n\n## Solutions tried\n\n### no-hoist all workspaces\n\nSolves the problem since there's no hoisting in the workspaces root node_modules, but for medium / large projects this is not an option because it doesn't scale (huge dependencies tree) and defeats the purposes of the workspaces in the first place.\n\n### Copy \"package-a\" in \"project-a\" using yalc\n\nIf we copy directly *package-a* in *project-a*:\n\n- *project-a* is responsible of *package-a* dependencies install\n\nThis ensures that there will be no differences between prod \u0026 dev results.\n\nBut copy is not free and costs more horse power, because in dev mode we want files to be copied on file change, which requires to have watchers on *package-a* that will trigger the copy operation. It doesn't scale if you want to chain package links, which can happen sometimes.\n\n### Colocate a devDep for each peerDep\n\nWe could make a trick in adding to *package-a* a devDependency for log-version and make this match the version provided by *project-a*.\n\nFollow the steps, having in mind that *package-a* is linked into *project-a*: \n\n```\nworkspaces\n  |-- node_modules\n    |-- log-version@1.0.0\n  |-- packages\n    |-- package-a\n    |-- node_modules // STEP 2\n      |-- log-version@1.1.0 // STEP 3\n    package.json\n      * peerDependency:\n        - log-version ^1.0.0\n      * devDependency:\n        - log-version@1.1.0\n\nproject-a\n  |-- node_modules\n    |-- log-version@1.1.0\n    |-- package-a // STEP 1\n  package.json\n    * dependency:\n      - log-version@1.1.0\n      - package-a\n```\n\nBut it requires you to make sure the project and the devDependency are the same for each peerDependency for this to work, which is a pain for the teams.\n\nLast but not least, using a peerDependency is usually involved because you want to use a single instance of a given dependency running in your application, so this \"trick\" is still not an option for some cases. It still is not the same as the *unlink* workflow.\n\n### Yarn PnP\n\nSince plug'n play changes the way dependencies are resolved, it might entirely solve this problem.\n\nIn fact, the branch *pnp* of this repo proves that it indeed works!\n\nBut when we tried to move to PnP we encountered other issues (that we might decide to overcome anyway), so at the moment we would want things to work without PnP unless we are sure it's the only way to make things work.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmbeaudru%2Fyarn-workspaces-peerdeps-resolution","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmbeaudru%2Fyarn-workspaces-peerdeps-resolution","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmbeaudru%2Fyarn-workspaces-peerdeps-resolution/lists"}