C.W.K.
Stream
Lesson 04 of 05 · published

PnP, Zero-Installs, Constraints

~12 min · yarn, concepts, pnp

Level 0Newbie
0 XP0/55 lessons0/16 achievements
0/80 XP to next level80 XP to go0% complete

Yarn Berry's signature ideas are PnP, zero-installs, and constraints. Each one deserves a paragraph.

Plug'n'Play (PnP). Instead of unpacking thousands of packages into node_modules, Yarn keeps them as zip files in .yarn/cache/. When your code does import foo from 'lodash', the generated .pnp.cjs file resolves that import to the exact byte range inside the cached zip. Result: faster installs (no unzipping), faster boot times, and undeclared deps fail loudly because they were never registered in the manifest. Trade-off: tools that don't speak PnP (some IDEs, older bundlers) need an SDK helper.

PnP fallback. If PnP breaks too much of your tooling, set nodeLinker: node-modules in .yarnrc.yml. Yarn switches back to a traditional node_modules layout while keeping the rest of Berry's improvements. You don't have to commit to PnP to use Berry.

Zero-installs. Commit .yarn/cache/ to Git. Now teammates and CI machines need only git clone — no install step. CI install times drop from minutes to seconds. The cost is a bigger Git repo (gigabytes if you have a lot of deps); the win is dramatic CI speedup.

Constraints. A JavaScript-based engine that enforces project-wide rules — every workspace must use the same React version, no package may depend on lodash directly, etc. Define rules in yarn.config.cjs; yarn constraints reports violations. Invaluable for monorepos that have grown beyond one team's heads.

Code

Switch off PnP if it breaks your tooling·yaml
# .yarnrc.yml at the repo root
nodeLinker: node-modules

# Berry now creates a regular node_modules and skips .pnp.cjs.
# You keep Berry's other features (cache, lockfile, workspaces, constraints)
# but tools that hate PnP work normally.
Constraints — one shared React version across workspaces·javascript
// yarn.config.cjs
module.exports = {
  constraints: async ({ Yarn }) => {
    for (const dep of Yarn.dependencies({ ident: 'react' })) {
      dep.update('19.0.0');
    }
  },
};

// Then run:
//   yarn constraints           — check
//   yarn constraints --fix     — auto-apply

External links

Exercise

In a Berry project, look at .yarnrc.yml and check whether nodeLinker is set. If PnP is the default, try installing one VS Code extension (the ZipFS extension + 'yarn dlx @yarnpkg/sdks vscode') to see how PnP integrates with editors. If it's painful, switch to nodeLinker: node-modules — Berry without PnP is still better than Classic.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.