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 sharednode_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:
terminal
Configuration file
Set the default linker strategy in yourbunfig.toml or globally in $HOME/.bunfig.toml:
bunfig.toml
Default behavior
The default linker strategy depends on your project’s lockfileconfigVersion:
configVersion | Using workspaces? | Default Linker |
|---|---|---|
1 | ✅ | isolated |
1 | ❌ | hoisted |
0 | ✅ | hoisted |
0 | ❌ | hoisted |
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)
--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:tree layout of node_modules
Resolution 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:tree layout of node_modules
Global virtual store
By default, store entries are materialized once into a global virtual store at<cache>/links/ and node_modules/.bun/<pkg>@<ver> is a symlink into it. Warm installs after rm -rf node_modules only create one symlink per package instead of copying every package’s files again, which is roughly 7× faster on a typical mid-size project. See the global store docs for the full layout, benchmarks, and tradeoffs.
Backend strategies
When an entry isn’t eligible for the global store (or the global store is disabled), Bun materializes it under the project using one of:- 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:terminal
- 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
-
Switch to hoisted mode for specific projects:
terminal
- Report 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
terminal
From pnpm
Isolated installs are conceptually similar to pnpm, so migration is direct:terminal
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
- 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