Yarn & Plug'n'Play (PnP / Zero Installs)

Discover how Yarn PnP replaces heavy node_modules folders with an in-memory resolution map (.pnp.cjs), zip archives, and instant zero-second builds.

Package Managers4 min readConcept 13 of 24

What is Yarn Plug'n'Play (PnP)?

Yarn Plug'n'Play (PnP) is an alternative module resolution strategy introduced in Yarn Berry (v2+) that completely eliminates the node_modules folder from Node.js projects.

Instead of extracting hundreds of thousands of loose dependency files onto disk, Yarn stores packages as compressed .zip archives inside .yarn/cache and generates a single Javascript file named .pnp.cjs containing a complete lookup map of all package locations and dependencies.

Why eliminate node_modules and move to Zero Installs?

Traditional node_modules folders create massive overhead: disk operations (thousands of fs.stat calls) slow down application startup, file copying during installs takes minutes, and flat hoisting introduces dangerous phantom dependencies.

Yarn PnP solves this by replacing disk folder traversal with an O(1) in-memory Javascript hash map lookup. Combined with Zero Installs (committing .yarn/cache and .pnp.cjs to Git), developers and CI servers can clone a repository and start executing code immediately in 0 seconds without running yarn install.

How Yarn PnP Resolves Packages at Runtime

When running Node.js with Yarn PnP enabled, .pnp.cjs injects custom resolution hooks into Node's internal module loader (Module._resolveFilename) and virtual file system layer (ZipFS).

When your code calls require('lodash') or import 'lodash', PnP inspects .pnp.cjs in memory, verifies that your project's package.json explicitly lists lodash as a dependency, and points Node directly into .yarn/cache/lodash.zip to read the file transparently.

Inspect Yarn PnP and Test In-Memory Resolution

Experience how Yarn PnP resolves dependencies directly from zip archives without a node_modules folder.

// Traditional node_modules Resolution (Legacy)
$ node server.js
// Recursive Directory Traversal on Disk
require("lodash");
// System Calls (O(N) Disk Operations)
1. fs.stat("./node_modules/lodash") -> ENOENT
2. fs.stat("../node_modules/lodash") -> ENOENT
3. fs.stat("/app/node_modules/lodash") -> FOUND!
// Result: 100,000+ unzipped files on disk
// Phantom import vulnerabilities allowed
Legacy node_modules Disk Hierarchy
node_modules/ (140 MB, 120,000 files)
express/
node_modules/
accepts/
lodash/ hoisted
Disk Bottleneck: Scanning folders on disk takes thousands of I/O operations. Code can access hoisted sub-dependencies directly, creating dangerous phantom dependencies.

Step through Yarn PnP architecture to compare node_modules vs .pnp.cjs resolution

Remember this

  • Yarn Plug'n'Play (PnP) replaces node_modules with an in-memory resolution table (.pnp.cjs) and .zip archives in .yarn/cache.
  • Zero Installs commits dependency zip files and resolution maps to Git for 0-second instant repo clones without yarn install.
  • PnP prevents phantom dependencies by strictly enforcing declared dependencies in package.json at resolution time.
  • Use yarn dlx @yarnpkg/sdks vscode for IDE integration and --loader ./.pnp.loader.mjs for ESM module imports.

Done with this concept?

Mark it complete to track your progress. No login needed.