bun-types
Version:
Type definitions and documentation for Bun, an incredibly fast JavaScript runtime
221 lines (148 loc) • 8.63 kB
text/mdx
---
title: "Isolated installs"
description: "Strict dependency isolation similar to pnpm's approach"
---
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:
```bash terminal icon="terminal"
# Use isolated installs
bun install --linker isolated
# Use traditional hoisted installs
bun install --linker hoisted
```
### Configuration file
Set the default linker strategy in your `bunfig.toml` or globally in `$HOME/.bunfig.toml`:
```toml bunfig.toml icon="settings"
[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:
```bash tree layout of node_modules icon="list-tree"
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 # Symlinks
```
### Resolution algorithm
1. **Central store** — All packages are installed in `node_modules/.bun/package@version/` directories
2. **Symlinks** — Top-level `node_modules` contains symlinks pointing to the central store
3. **Peer resolution** — Complex peer dependencies create specialized directory names
4. **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:
```bash tree layout of node_modules icon="list-tree"
# 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:
```bash terminal icon="terminal"
bun install --linker isolated --verbose
```
This 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_modules` structure
- **Dynamic imports** — Runtime imports that don't follow Node.js resolution
- **Build tools** — Tools that scan `node_modules` directly
If you encounter issues, you can:
1. **Switch to hoisted mode** for specific projects:
```bash terminal icon="terminal"
bun install --linker hoisted
```
2. **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
```bash terminal icon="terminal"
# Remove existing node_modules and lockfiles
rm -rf node_modules package-lock.json yarn.lock
# Install with isolated linker
bun install --linker isolated
```
### From pnpm
Isolated installs are conceptually similar to pnpm, so migration should be straightforward:
```bash terminal icon="terminal"
# Remove pnpm files
$ rm -rf node_modules pnpm-lock.yaml
# Install with Bun's isolated linker
bun install --linker isolated
```
The 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](/docs/pm/workspaces) — Monorepo workspace management
- [Package manager > Lockfile](/docs/pm/lockfile) — Understanding Bun's lockfile format
- [CLI > install](/docs/pm/cli/install) — Complete `bun install` command reference