Skip to content

Drop netlify-cli from the dependency tree - #131

Merged
ledwards merged 1 commit into
mainfrom
dependency-cleanup
Aug 12, 2026
Merged

Drop netlify-cli from the dependency tree#131
ledwards merged 1 commit into
mainfrom
dependency-cleanup

Conversation

@ledwards

Copy link
Copy Markdown
Contributor

Replaces #130, which reported CVE-2023-45133 (arbitrary code execution in @babel/traverse).

The report was right; the patch wasn't

@babel/traverse@7.16.3 really was in our tree, and the CVE is genuinely fixed in 7.23.2. But #130 added overrides to package.json without regenerating package-lock.json, and overrides only affects resolution during npm install. CI runs npm ci, which installs strictly from the lockfile — so the vulnerable version would have kept installing unchanged.

The actual problem

@babel/traverse arrived four levels down through netlify-cli, which was:

  • pinned at ^6.14.7 while current is 27.x
  • sitting in dependencies, not devDependencies
  • used by exactly one script, npm start, for local dev
  • 1987 of the 2176 packages in the lockfile — 91% of the dependency graph

All of that installed on every CI run and every Netlify deploy, to support running netlify dev on a laptop.

Why not just upgrade it

Tried that first; it doesn't work at Node 20:

  • netlify-cli 27 requires Node >=22.13.0, and CI + netlify.toml are pinned to Node 20. Bumping Node is a production build change, not a dependency cleanup.
  • netlify-cli 26 — the newest line supporting Node 20 — pins @opentelemetry/api@~1.8.0, which collides with vitest's ^1.9.0. npm can't resolve it without --legacy-peer-deps, and baking that into how everyone installs is worse than the disease.

What this does instead

npm start calls npx netlify dev, fetching the CLI on demand. Also removes ai@^3.0.18, which nothing imports — I grepped for require("ai"), from "ai", and @ai-sdk and there are no hits.

before after
packages in lockfile 2176 135
lockfile 24,706 lines 2,047
npm audit 6 (4 high) 2 low

@babel/traverse is gone from the tree entirely, so the CVE is resolved at the source rather than pinned around. npm audit fix cleared the remaining high-severity advisories (nanoid, postcss, undici).

What's left

2 low-severity advisories for vue, reached through aalib.js — the library that renders the terminal's ASCII art. It's unmaintained and there's no drop-in replacement, so that needs its own decision rather than a quiet bump.

Tradeoff

The CLI version is no longer pinned, so npx will fetch whatever is current. For a tool that only runs netlify dev against a static site, and never runs in CI or during the deploy, that seems worth 94% of the dependency graph. If you'd rather pin it, the alternative is a global install documented in the README.

Test plan

  • npm install from a clean node_modules
  • npm test — 95/95
  • npm run builddist/ identical in shape
  • Confirmed @babel/traverse and netlify-cli are both absent from the regenerated lockfile

🤖 Generated with Claude Code

CVE-2023-45133 (arbitrary code execution in @babel/traverse) was reported
against this repo in #130. The vulnerable package was real — 7.16.3, fixed in
7.23.2 — but it arrived four levels down through netlify-cli, which was pinned
at ^6.14.7 while current is 27.x, and sat in `dependencies` despite being used
by exactly one script for local dev.

netlify-cli accounted for 1987 of the 2176 packages in the lockfile. 91% of the
dependency graph, installed on every CI run and every deploy, to support
`npm start` on a developer's laptop. `npm start` now calls `npx netlify dev`,
which fetches it on demand.

Upgrading in place was tried first and does not work at Node 20: netlify-cli 27
requires Node >= 22.13, and 26 — the newest line that supports Node 20 — pins
@opentelemetry/api ~1.8.0 against vitest's ^1.9.0, which npm cannot resolve.

Also removes `ai@^3.0.18`, which nothing imports.

  packages    2176 -> 135
  lockfile    24706 -> 2047 lines
  audit       6 vulnerabilities (4 high) -> 2 low

@babel/traverse is gone from the tree entirely, so the reported CVE is resolved
at the source rather than pinned around. The 2 remaining advisories are vue,
reached through aalib.js, which renders the terminal's ASCII art and has no
maintained alternative — that needs its own decision.

The tradeoff is that the CLI version is no longer pinned. For a tool that only
runs `netlify dev` against a static site, and never in CI or the deploy, that
is worth 94% of the dependency graph.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ledwards
ledwards merged commit 19040b7 into main Aug 12, 2026
6 checks passed
@ledwards
ledwards deleted the dependency-cleanup branch August 12, 2026 23:57
@ledwards ledwards mentioned this pull request Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant