UNPKG

bun-types

Version:

Type definitions and documentation for Bun, an incredibly fast JavaScript runtime

221 lines (148 loc) 8.63 kB
--- 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