Safeguard
Developer Tools•

pnpm nodeLinker isolated or hoisted: what changes for security?

pnpm's default isolated layout symlinks from a virtual store and limits phantom access. Hoisted gives a flat node_modules. What each means, when to switch.

Safeguard Security Team
4 min read

pnpm's nodeLinker setting defaults to isolated, which symlinks dependencies from a virtual store at node_modules/.pnpm. Setting it to hoisted builds a flat node_modules like npm or Yarn Classic. Isolated limits what your code can import by accident. Hoisted trades that for compatibility with tools that dislike symlinks.

The values

The pnpm docs describe nodeLinker as the linker used to install Node packages. The options are isolated, hoisted, pnp, loaded or a loaded-linker object. The two most common:

ValueLayoutWhen to choose it
isolated (default)Dependencies symlinked from a virtual store at node_modules/.pnpmMost projects
hoistedFlat node_modules without symlinks, like npm or Yarn ClassicTooling that fails with symlinks, some serverless hosts, publishing with bundledDependencies, running Node with the preserve-symlinks flag

Those reasons for hoisted are the docs' own list. The docs also note that for serverless hosts that lack symlink support, bundling your application before deployment is an alternative.

The security angle: phantom dependencies

In a flat layout, your code can import packages you never declared, because a transitive dependency happens to sit at the top. In isolated layout, a package sees its declared dependencies. This reduces accidental reliance on code whose version you did not choose.

pnpm still has softening settings. By default hoist is true and hoists all dependencies into node_modules/.pnpm/node_modules, which makes unlisted dependencies accessible to packages inside node_modules, but not to your own code in the project root. The docs call this semistrict. publicHoistPattern moves matching packages to the root node_modules, so application code can reach them, and shamefullyHoist (default false) hoists everything to the root.

SettingDefaultEffect on exposure
hoisttrueDependencies reachable by other packages through a hidden folder
hoistPatternall packagesNarrow it to only flawed packages that need it
publicHoistPatternnoneMoves matches to the root, exposing them to application code
shamefullyHoistfalseHoists all to the root, the most exposure

The docs recommend narrowing hoistPattern to exclusively hoist the packages known to have phantom dependency problems.

How to decide

  1. Start with isolated. Run your build and tests.
  2. If a tool breaks, find the cause. Often it imports something it never declared.
  3. Fix with the narrowest setting: add the missing dependency, or add one name to publicHoistPattern.
  4. Choose hoisted only for a documented reason, and write the reason in the repository.
  5. Re-run the install in CI to confirm both layouts behave.

Layout affects what runs, not which versions install. Version pinning still comes from the lockfile and your frozen install. See phantom dependencies and how pnpm blocks them, and what scanners read in a pnpm workspace.

What layout does not change

Isolated installs do not make a malicious package safe. Install scripts, a compromised release and a poisoned lockfile are separate risks with separate controls. Layout limits accidental access, not deliberate access: a malicious package can still read files on disk.

Where Safeguard fits

Safeguard's dependency scanning and SBOM generation read lockfiles whatever linker you use, and reachability analysis helps decide which vulnerable packages your code actually reaches. A free scan is at https://gold.safeguard.sh/scan.

Quick check

What is the default pnpm nodeLinker?

isolated, which symlinks dependencies from a virtual store at node_modules/.pnpm.

Does isolated mode stop malicious packages?

No. It limits accidental imports of undeclared packages. A package you declared can still run code, so script controls and review still matter.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.