note

Let me explain the concept of hoisting in package managers and why pnpm has the --shamefully-hoist option:

  1. Package Hoisting in npm/yarn:

    • Traditional package managers like npm and yarn use a concept called “hoisting”
    • When you install dependencies, they “hoist” packages to the top-level node_modules directory whenever possible
    • This means that if package A and package B both depend on package C, there will be only one copy of C in the top-level node_modules
    • This saves disk space but creates what’s called a “flat” dependency structure
  2. pnpm’s approach:

    • pnpm uses a fundamentally different approach with a strict dependency structure
    • It keeps dependencies in a content-addressable store and uses symlinks
    • Each package can only access dependencies it has explicitly declared
    • This creates a more accurate node_modules tree that matches the actual dependency graph
    • It prevents the “phantom dependency” problem (when code uses packages not declared in package.json)
  3. Why --shamefully-hoist exists:

    • Some packages are written with the assumption that dependencies will be hoisted (the npm/yarn way)
    • These packages might try to access modules they haven’t declared as dependencies
    • The --shamefully-hoist flag forces pnpm to mimic npm’s hoisting behavior
    • It’s called “shamefully” because it sacrifices pnpm’s correctness guarantees for compatibility
  4. When you might need it:

    • When working with older packages that weren’t written with pnpm in mind
    • When dealing with packages that have implicit dependencies
    • With tooling that expects a flat node_modules structure