Docs: plugin installation silently runs `bun install`/`npm ci` — automatic dependency installation is undocumented

Status Fixed / completed
Maintainer reply None cached
Activity 2 comments · opened Aug 7, 2026 · closed Aug 11, 2026
Update 2026-08-07: re-verified on v2.1.224 — behavior unchanged (identical installer table in the binary, and a live test with a minimal three-plugin marketplace reproduced all three cases: bun.lock → auto-install, no lockfile → nothing, yarn.lock → silently skipped). Details in this comment. Also newly observed: claude plugin uninstall does not remove the cached version directory, so auto-installed node_modules persists on disk after uninstall.

Summary

When Claude Code installs a plugin from a marketplace, it automatically installs the plugin's Node.js dependencies into the cached copy — but this behavior is not mentioned anywhere in the plugin docs (plugins, plugins-reference, discover-plugins) or the CHANGELOG. Developers installing plugins have no way to know that a plugin can pull hundreds of MB of node_modules onto disk, and plugin authors have no documented guidance on which lockfiles are supported.

Observed behavior (Claude Code v2.1.220, re-verified on v2.1.224, macOS)

Installing the qmd plugin (marketplace repo ~11 MB, 179 items) produced a cache directory of ~230 MB / 9,000+ items at ~/.claude/plugins/cache/qmd/qmd/0.1.0/ — 212 MB of which is a node_modules created by an automatic bun install within a minute of install. No user or session ran the install.

Note: this is not specific to qmd — it's just the plugin that surfaced the behavior. Any plugin shipping a package.json plus a supported lockfile triggers the automatic install. This was confirmed with a synthetic minimal marketplace containing three one-dependency test plugins (see the v2.1.224 verification comment): the bun.lock plugin got its dependencies auto-installed, while otherwise-identical plugins with no lockfile or a yarn.lock did not.

From observed behavior and strings in the bundled CLI, the logic appears to be:

  1. After copying the plugin into the cache, if the plugin directory contains a package.json, check for a lockfile:
  • bun.lock / bun.lockbbun install --frozen-lockfile --ignore-scripts
  • npm-shrinkwrap.json / package-lock.jsonnpm ci --ignore-scripts
  1. yarn.lock / pnpm-lock.yaml are explicitly skipped with: "Skipped: yarn/pnpm lockfiles are not supported (resolution-time hooks bypass --ignore-scripts). Use bun or npm."
  2. The install runs with a 60-second timeout; --ignore-scripts means no lifecycle/postinstall scripts execute.
  3. No package.json (or no supported lockfile) → nothing runs.

Corroborating datapoint: claude-mem 13.12.4 ships bun.lock and has a 473 MB node_modules in cache; 13.4.0 (same plugin, package.json but no lockfile) has none.

Why this should be documented

  • Disk usage: each cached plugin version gets its own full dependency install and old versions are not cleaned up — three qmd versions × 212 MB each on this machine. Uninstalling a plugin also leaves its cached version directory (including node_modules) on disk. Users deserve to know where the space goes and that it's expected.
  • Plugin author guidance: authors need to know that shipping a bun.lock/package-lock.json opts them into automatic installs, that yarn/pnpm lockfiles are rejected, and that postinstall scripts will never run (so native builds relying on them will not work).
  • Security posture (worth advertising!): --ignore-scripts + frozen/ci installs is a deliberate, good design — no plugin-supplied code executes at install time. Documenting it would answer an obvious supply-chain question.
  • Update semantics: claude plugin update and marketplace auto-update re-run this install for each new version directory, which affects update duration and disk growth.

Suggested doc changes

  • A "Plugin dependencies" section in the plugins reference covering: trigger conditions, supported lockfiles, exact commands/flags, the 60 s timeout, yarn/pnpm rejection, and failure behavior.
  • A note in the marketplace/install docs about per-version cache layout and disk implications.
  • Optionally: document whether a setting exists (or add one) to disable automatic dependency installation.

Environment

  • Claude Code v2.1.220 (original report) and v2.1.224 (re-verified 2026-08-07), macOS (darwin arm64)

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗