# `NPM.Install.Linker`
[🔗](https://github.com/elixir-volt/npm_ex/blob/v0.7.4/lib/npm/install/linker.ex#L1)

Creates `node_modules` from the global cache.

Supports multiple linking strategies:
- `:symlink` (default) — symlinks from `node_modules/pkg` to cache
- `:copy` — full file copy

Uses a hoisted layout where packages are placed as high in the tree
as possible, only nesting when version conflicts occur.

# `nested_info`

```elixir
@type nested_info() :: %{required(String.t()) =&gt; term()}
```

# `resolved`

```elixir
@type resolved() :: %{required(String.t()) =&gt; NPM.Lockfile.entry()}
```

# `strategy`

```elixir
@type strategy() :: :symlink | :copy
```

# `hoist`

```elixir
@spec hoist(resolved()) :: [{String.t(), String.t()}]
```

Hoist packages for a flat `node_modules` layout.

Returns a list of `{name, version}` tuples representing the top-level
packages. When multiple versions of a package exist, the most commonly
depended-on version gets hoisted.

# `link`

```elixir
@spec link(resolved(), String.t(), strategy()) :: :ok | {:error, term()}
```

Link all resolved packages into `node_modules`.

First populates the global cache, then creates the `node_modules` tree.

# `link_bins`

```elixir
@spec link_bins(String.t(), [{String.t(), String.t()}]) :: :ok
```

Create `node_modules/.bin/` symlinks for packages with `bin` entries.

Reads each package's `package.json` for the `bin` field and creates
executable symlinks in `.bin/`.

# `link_nested`

```elixir
@spec link_nested(nested_info(), resolved(), String.t(), strategy()) :: :ok
```

Link nested packages into parent package `node_modules/` subdirectories.

For each nested package, resolves which version each parent needs and
creates `parent_pkg/node_modules/nested_pkg/` with the correct version.

# `prune`

```elixir
@spec prune(String.t(), MapSet.t()) :: :ok
```

Remove packages from `node_modules` that are not in the expected set.

Handles both regular and scoped packages (`@scope/pkg`).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
