Yarn Berry nodeLinker Errors - Fix PnP vs node-modules in CI
Yarn Berry’s nodeLinker setting decides how dependencies are installed: Plug’n’Play (no node_modules), node-modules, or pnpm. CI breaks when the tooling expects one layout but the project is configured for another.
What this error means
Under Yarn Berry, CI either finds an empty/absent node_modules (because PnP is the linker) and tooling cannot resolve modules, or a tool errors out specifically because PnP is active. The fix is to make the linker match what your tooling supports.
# .yarnrc.yml has: nodeLinker: pnp
# a tool that walks node_modules then fails:
Error: Cannot find module 'react'
(node_modules is empty under Plug'n'Play)
# or a tool that does not understand PnP throws its own resolution errorCommon causes
PnP is active but tooling expects node_modules
With nodeLinker: pnp, there is no node_modules - dependencies are resolved via .pnp.cjs. Tools that scan node_modules directly cannot find anything.
The CI config does not match .yarnrc.yml
A workflow assuming a node-modules layout (caching node_modules, running tools unaware of PnP) conflicts with a project set to PnP, or vice versa.
How to fix it
Choose a linker your tooling supports
If your tools need a real node_modules, set the node-modules linker explicitly.
# .yarnrc.yml
nodeLinker: node-modulesOr make CI PnP-aware
- Keep PnP and run scripts via
yarn <script>so the PnP runtime is injected. - Use the Yarn SDKs/loader for tools that support PnP (e.g. via
yarn dlx @yarnpkg/sdks). - Cache
.yarn/cacheand.pnp.cjsinstead of node_modules under PnP.
How to prevent it
- Pick a nodeLinker that matches your toolchain and stick to it.
- Align CI caching with the chosen linker (PnP vs node-modules).
- Run tools through yarn so PnP resolution is applied.