# Source: https://bun.com/docs/pm/isolated-installs.md

> ## Documentation Index
> Fetch the complete documentation index at: https://bun.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Isolated installs

> 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" theme={"theme":{"light":"github-light","dark":"dracula"}}
# 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" theme={"theme":{"light":"github-light","dark":"dracula"}}
[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" theme={"theme":{"light":"github-light","dark":"dracula"}}
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" theme={"theme":{"light":"github-light","dark":"dracula"}}
# 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" theme={"theme":{"light":"github-light","dark":"dracula"}}
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" theme={"theme":{"light":"github-light","dark":"dracula"}}
   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" theme={"theme":{"light":"github-light","dark":"dracula"}}
# 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" theme={"theme":{"light":"github-light","dark":"dracula"}}
# 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](/pm/workspaces) — Monorepo workspace management
* [Package manager > Lockfile](/pm/lockfile) — Understanding Bun's lockfile format
* [CLI > install](/pm/cli/install) — Complete `bun install` command reference