Understanding bun install --isolated

I am a developer from Vietnam.
When developers first switch from npm or pnpm to Bun, one option that often causes confusion is:
bun install --isolated
At first glance, it sounds similar to pnpm’s architecture. But the reality is more nuanced.
This article explains:
What
--isolatedactually does in BunHow Bun normally installs packages
How it compares with npm and pnpm
Why this option exists
When you should (and should not) use it
Quick Summary
| Package Manager | Default Behavior | Shared Global Store | Hoisting | Strict Dependency Isolation |
|---|---|---|---|---|
| npm | Flat node_modules | No | Yes | Weak |
| pnpm | Symlinked store | Yes | Partial | Strong |
| Bun | Fast npm-like install | Global cache | Yes | Weak |
| Bun --isolated | Isolated dependency layout | Global cache | Limited | Stronger |
The important distinction: bun install --isolated is NOT the same architecture as pnpm.
It improves dependency isolation behavior, but Bun still uses a different installation model internally.
First: How Bun Normally Installs Packages
By default, Bun behaves similarly to npm/Yarn classic.
First: How Bun Normally Installs Packages
By default, Bun behaves similarly to npm/Yarn classic.
Example:
bun install
Bun will:
Download packages into a global cache
Create a traditional node_modules
Hoist many dependencies to the top level
Optimize aggressively for speed
Typical result:
node_modules/
react/
lodash/
some-package/
This layout is very compatible with the Node.js ecosystem.
It also allows packages to accidentally access undeclared dependencies due to hoisting.
Example:
{
"dependencies": {
"package-a": "^1.0.0"
}
}
If package-a internally uses lodash but forgets to declare it, it may still work because another package already installed lodash at the top level.
This is known as:
phantom dependencies
hidden dependency leakage
undeclared dependency access
npm historically allowed this behavior.
Problems
Example of "package.json":
{
"dependencies": {
"react": "^19.0.0"
}
}
And the code uses:
import _ from "lodash"
It may still run if:
lodash exists somewhere in node_modules
another package has already installed lodash
This results in hidden bugs and errors. In monorepo, this issue is even worse. Because project A and project B in monorepo may have different versions of the same dependency. If both projects use the same dependency but with different versions, the package may not work as expected.
What --isolated Changes
When using: bun install --isolated, bun changes the dependency resolution layout to make packages more isolated from each other.
The goal:
reduce accidental dependency access
improve determinism
make installs closer to declared dependencies only
This means a package can no longer freely access dependencies that it did not explicitly declare.
Example
Imagine this dependency tree:
app
├── package-a
│ └── lodash
└── package-b
And package-b tries:
require("lodash");
even though it never declared lodash.
Normal Bun Install
This might still work because lodash may be hoisted.
node_modules/
lodash/
package-a/
package-b/
Bun Install with --isolated
Now dependency visibility becomes stricter.
package-b may fail because lodash is not part of its declared dependencies.
This behavior is closer to:
pnpm strictness
modern monorepo correctness
reproducible builds
Performance: Isolated installs are highly parallelizable, making bun install up to 10x faster on Windows. Warm installs in monorepos can also see a 7x speedup through the experimental global store.
Does Bun Use a Shared Package Store Like pnpm?
This is where many people misunderstand Bun.
pnpm Architecture
pnpm uses a content-addressable global store.
Packages are stored once globally:
~/.pnpm-store
Projects then use:
symlinks
hard links
instead of copying full package contents.
This is why pnpm is extremely disk-efficient.
Example:
project/node_modules/.pnpm/
pnpm creates a virtualized dependency graph.
This architecture is core to pnpm itself.
Bun Architecture
Bun also has a global cache.
But Bun does NOT implement the same virtual symlink graph architecture as pnpm.
Instead, Bun prioritizes:
ultra-fast installation
compatibility
simpler filesystem behavior
So even with --isolated:
Bun still uses its own install strategy
Bun does not become "pnpm mode"
Bun does not recreate pnpm's .pnpm virtual store structure
This is a key distinction.
Setting it as Default
If you are working in a monorepo (workspaces), isolated mode is now the default as of Bun v1.3. For other projects, you can force it globally by adding this to your bunfig.toml:
[install]
linker = "isolated"


