Bun provides an alternative package installation strategy called isolated installs that creates strict dependency isolation similar to pnpm's approach. This mode prevents phantom dependencies and ensures reproducible, deterministic builds.
This is the default installation strategy for new workspace/monorepo projects (with configVersion = 1 in the lockfile). Existing projects continue using hoisted installs unless explicitly configured.
What are isolated installs?
Isolated installs create a non-hoisted dependency structure where packages can only access their explicitly declared dependencies. This differs from the traditional "hoisted" installation strategy used by npm and Yarn, where dependencies are flattened into a shared node_modules directory.
Key benefits
- Prevents phantom dependencies — Packages cannot accidentally import dependencies they haven't declared
- Deterministic resolution — Same dependency tree regardless of what else is installed
- Better for monorepos — Workspace isolation prevents cross-contamination between packages
- Reproducible builds — More predictable resolution behavior across environments
Using isolated installs
Command line
Use the --linker flag to specify the installation strategy:
# Use isolated installs
bun install --linker isolated
# Use traditional hoisted installs
bun install --linker hoistedConfiguration file
Set the default linker strategy in your bunfig.toml or globally in $HOME/.bunfig.toml:
[install]
linker = "isolated"Default behavior
The default linker strategy depends on your project's lockfile configVersion:
configVersion | Using workspaces? | Default Linker |
|---|---|---|
1 | ✅ | isolated |
1 | ❌ | hoisted |
0 | ✅ | hoisted |
0 | ❌ | hoisted |
New projects: Default to configVersion = 1. In workspaces, v1 uses the isolated linker by default; otherwise it uses hoisted linking.
Existing Bun projects (made pre-v1.3.2): If your existing lockfile doesn't have a version yet, Bun sets configVersion = 0 when you run bun install, preserving the previous hoisted linker default.
Migrations from other package managers:
- From pnpm:
configVersion = 1(using isolated installs in workspaces) - From npm or yarn:
configVersion = 0(using hoisted installs)
You can override the default behavior by explicitly specifying the --linker flag or setting it in your configuration file.
How isolated installs work
Directory structure
Instead of hoisting dependencies, isolated installs create a two-tier structure:
node_modules/
├── .bun/ # Central package store
│ ├── package@1.0.0/ # Versioned package installations
│ │ └── node_modules/
│ │ └── package/ # Actual package files
│ ├── @scope+package@2.1.0/ # Scoped packages (+ replaces /)
│ │ └── node_modules/
│ │ └── @scope/
│ │ └── package/
│ └── ...
└── package-name -> .bun/package@1.0.0/node_modules/package # SymlinksResolution algorithm
- Central store — All packages are installed in
node_modules/.bun/package@version/directories - Symlinks — Top-level
node_modulescontains symlinks pointing to the central store - Peer resolution — Complex peer dependencies create specialized directory names
- Deduplication — Packages with identical package IDs and peer dependency sets are shared
Workspace handling
In monorepos, workspace dependencies are handled specially:
- Workspace packages — Symlinked directly to their source directories, not the store
- Workspace dependencies — Can access other workspace packages in the monorepo
- External dependencies — Installed in the isolated store with proper isolation
Comparison with hoisted installs
| Aspect | Hoisted (npm/Yarn) | Isolated (pnpm-like) |
|---|---|---|
| Dependency access | Packages can access any hoisted dependency | Packages only see declared dependencies |
| Phantom dependencies | ❌ Possible | ✅ Prevented |
| Disk usage | ✅ Lower (shared installs) | ✅ Similar (uses symlinks) |
| Determinism | ❌ Less deterministic | ✅ More deterministic |
| Node.js compatibility | ✅ Standard behavior | ✅ Compatible via symlinks |
| Best for | Single projects, legacy code | Monorepos, strict dependency management |
Advanced features
Peer dependency handling
Isolated installs handle peer dependencies through sophisticated resolution:
# Package with peer dependencies creates specialized paths
node_modules/.bun/package@1.0.0_react@18.2.0/The directory name encodes both the package version and its peer dependency versions, ensuring each unique combination gets its own installation.
Backend strategies
Bun uses different file operation strategies for performance:
- Clonefile (macOS) — Copy-on-write filesystem clones for maximum efficiency
- Hardlink (Linux/Windows) — Hardlinks to save disk space
- Copyfile (fallback) — Full file copies when other methods aren't available
Debugging isolated installs
Enable verbose logging to understand the installation process:
bun install --linker isolated --verboseThis shows:
- Store entry creation
- Symlink operations
- Peer dependency resolution
- Deduplication decisions
Troubleshooting
Compatibility issues
Some packages may not work correctly with isolated installs due to:
- Hardcoded paths — Packages that assume a flat
node_modulesstructure - Dynamic imports — Runtime imports that don't follow Node.js resolution
- Build tools — Tools that scan
node_modulesdirectly
If you encounter issues, you can:
Switch to hoisted mode for specific projects:
bashbun install --linker hoistedReport compatibility issues to help improve isolated install support
Performance considerations
- Install time — May be slightly slower due to symlink operations
- Disk usage — Similar to hoisted (uses symlinks, not file copies)
- Memory usage — Higher during install due to complex peer resolution
Migration guide
From npm/Yarn
# Remove existing node_modules and lockfiles
rm -rf node_modules package-lock.json yarn.lock
# Install with isolated linker
bun install --linker isolatedFrom pnpm
Isolated installs are conceptually similar to pnpm, so migration should be straightforward:
# Remove pnpm files
$ rm -rf node_modules pnpm-lock.yaml
# Install with Bun's isolated linker
bun install --linker isolatedThe main difference is that Bun uses symlinks in node_modules while pnpm uses a global store with symlinks.
When to use isolated installs
Use isolated installs when:
- Working in monorepos with multiple packages
- Strict dependency management is required
- Preventing phantom dependencies is important
- Building libraries that need deterministic dependencies
Use hoisted installs when:
- Working with legacy code that assumes flat
node_modules - Compatibility with existing build tools is required
- Working in environments where symlinks aren't well supported
- You prefer the simpler traditional npm behavior
Related documentation
- Package manager > Workspaces — Monorepo workspace management
- Package manager > Lockfile — Understanding Bun's lockfile format
- CLI > install — Complete
bun installcommand reference