Plugin loading reference changedplugins/loading
Nearest release: v2.1.287, published 5 hours before upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Upstream edited this page at 1 Oct 2026 22:47 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 1 Oct 2026 23:07 UTC.
Upstream edited
Recorded here
Lines+26added
Lines−20removed
From line
206
where the diff opens
First seen
25 Sep 2026
this site's first read of the page
Recorded edits8to this page, all time
The whole hunk
from line 206, old and new numbered
/
from line 206
206206
207207#### When the dependency install runs
208208
209Claude Code runs the install inside the copied version directory each time it creates one:
209Claude Code installs the dependencies into the copied version directory each time it creates one:
210210
211211* When you install a plugin
212212* When Claude Code updates a plugin to a new version
from line 214
214214
215215For a relative-path plugin [loaded in place](#in-place-and-copied-plugins) from a local-directory marketplace, Claude Code doesn't install the dependencies into the source directory. Install them there yourself, or from a hook into [`${CLAUDE_PLUGIN_DATA}`](/docs/en/plugins/components#path-variables-and-persistent-data).
216216
217The install runs only when the plugin's root directory contains both a `package.json` and a supported lockfile. The lockfile decides which command Claude Code runs:
217The install runs only when the plugin's root directory contains both a `package.json` and a supported lockfile.
218218
219| Lockfile | Command |
219The lockfile decides which package manager Claude Code runs:
220
221| Lockfile | Package manager |
220222| :- | :- |
221| `bun.lock` or `bun.lockb` | `bun install --frozen-lockfile --ignore-scripts` |
222| `npm-shrinkwrap.json` or `package-lock.json` | `npm ci --ignore-scripts` |
223| `bun.lock` | Bun |
224| `npm-shrinkwrap.json` or `package-lock.json` | npm |
223225
224If a plugin contains more than one of these lockfiles, Claude Code uses the first match, checking in order: `bun.lock`, `bun.lockb`, `npm-shrinkwrap.json`, `package-lock.json`.
226If a plugin contains more than one of these lockfiles, Claude Code uses the first match, checking in order: `bun.lock`, `npm-shrinkwrap.json`, `package-lock.json`.
225227
226Claude Code skips the install for Yarn and pnpm lockfiles and for a `bunfig.toml` beside the Bun lockfile:
228Claude Code skips the install in these lockfile cases:
227229
228* If your plugin has only a `yarn.lock` or `pnpm-lock.yaml`, replace it with an npm lockfile
229* If a `bunfig.toml` is in the same directory as the Bun lockfile, remove the `bunfig.toml`, or replace the Bun lockfile with an npm lockfile
230* **`bun.lockb`**: Bun's binary lockfile can't be checked. Ship a text `bun.lock` or an npm lockfile instead
231* **`yarn.lock` or `pnpm-lock.yaml`**: replace it with an npm lockfile
232* **A lockfile in a format Claude Code doesn't read**: an npm lockfile needs a `lockfileVersion` of `2` or `3`, which npm 7 or later writes, and a `bun.lock` needs a `lockfileVersion` no higher than `2`
230233
231234Include an npm lockfile to reach the most users. Claude Code runs the matched lockfile's package manager from the user's PATH and doesn't try the other lockfile instead if that package manager is missing.
232235
from line 239
236239
237240Claude Code constrains this dependency install so that no code from the plugin or its packages executes during it, and bounds how long it can run:
238241
239* **Frozen resolution**: Bun and npm install exactly what the lockfile pins, and fail rather than re-resolve versions when `package.json` and the lockfile disagree
242* **Registry packages only**: every dependency must be a registry package pinned in the lockfile to an exact version. A plugin with a git, GitHub, folder, workspace, or linked dependency gets no install.
243* **`https` downloads**: a download link in the lockfile must use `https`, unless it points at the installing user's own default npm registry.
244* **A separate install folder**: the package manager runs in a folder of its own that holds only a copy of the checked dependency list, so npm and Bun don't read the plugin's `.npmrc`, `.env`, or `bunfig.toml`. When the install succeeds, Claude Code moves the resulting `node_modules` into the plugin.
245* **Frozen resolution**: the install uses exactly the versions the lockfile pins, and Claude Code skips it when `package.json` and the lockfile don't list the same dependencies
240246* **No lifecycle scripts**: `--ignore-scripts` keeps `preinstall`, `install`, and `postinstall` scripts from running, so dependencies that build native modules in those scripts download but don't compile during this install
247* **No overrides or patches**: a plugin whose `package.json` sets npm `overrides` gets no install from an npm lockfile, and a plugin that sets Bun `patchedDependencies` gets no install from `bun.lock`
241248* **60-second timeout**: Claude Code stops an install that runs longer and treats it as failed
242249
243250Claude Code fetches an npm-source plugin before this dependency install, and none of the package's own install scripts run during the fetch. See [npm plugin source](/docs/en/plugins/marketplace-reference#npm-plugin-source).
from line 255
248255
249256#### When the dependency install fails or is skipped
250257
251A failed or skipped install never blocks the plugin, and each case leaves a different sign:
258A failed or skipped install never blocks the plugin, which then loads without the dependencies. Each case leaves a different sign:
252259
253* A failed install, or one skipped because of a Yarn or pnpm lockfile or a `bunfig.toml`, appears as a warning in the `claude --debug` output
260* A failed install, or one skipped because of its lockfile or one of the [limits on the install](#limits-on-the-dependency-install), appears in the `claude --debug` output as a `Plugin dependency install warning` line that states the reason
254261* A plugin with a `package.json` and no lockfile is skipped without a log entry
255* A timed-out install can leave a partial `node_modules` tree in the cached copy
256262
257When the automatic install can't provide a dependency, install it from a hook into the [persistent data directory](/docs/en/plugins/components#path-variables-and-persistent-data). That includes packages that need their lifecycle scripts to build, Python dependencies, and plugins locked with Yarn or pnpm.
263When the automatic install can't provide a dependency, install it from a hook into the [persistent data directory](/docs/en/plugins/components#path-variables-and-persistent-data). That includes packages that need their lifecycle scripts to build, Python dependencies, plugins locked with Yarn or pnpm, and dependencies that aren't registry packages, such as git dependencies.
258264
259265## Versions and updates
260266
No line in this hunk matches that.