Skip to content
← Blog

Technical explainer

The side-project graveyard: vulnerable packages you forgot about

3 min read

Open your ~/code directory. Count the folders. Now count the ones you've opened in the last month. The ratio is the problem.

A typical vibe-coder laptop has dozens of half-finished side projects. Each was generated by a different AI tool in a different mood for a different idea. Each has its own node_modules (or .venv, or both). Each set of dependencies was the bleeding edge on the day you scaffolded — and has sat untouched ever since.

You're not maintaining those projects. You're hosting them.

What's still on your disk

Run this for a quick reality check:

find ~/code -name node_modules -type d -prune | wc -l
find ~/code -name '.venv' -o -name 'venv' -prune | wc -l

If those numbers shock you, you're not alone. Each folder contains hundreds of packages. Some of those packages have had vulnerabilities disclosed since you installed them. Some have had compromised versions published since you installed them — but you have the uncompromised version pinned, so you'd never know unless something on your disk triggered the malicious code path.

Which is the next question: what can trigger them?

Ways the old graveyard reaches up to bite you

It's not just inert bytes. Stale node_modules can re-enter the running set in surprisingly mundane ways:

  • You cd in and run npm test. Lifecycle scripts may fire. If you had a malicious postinstall that was added between when you installed and when you walked away, that already ran. But scripts in package.json (test, start, prepare) can also trigger code paths inside node_modules.
  • You re-enable a project and npm install. With a stale lockfile, npm pulls in updated transitive deps. The new versions might be hijacked. Now your old project has new attack surface.
  • An AI agent indexes your filesystem. Modern AI coding tools scan code in your project folder, and some can cd into siblings on their own. A malicious node_modules directory three projects over could end up in their context — or worse, get exec'd.
  • You accidentally activate the wrong venv. A Python venv from 2024 with a since-compromised dependency. You source it for a quick experiment. Whatever was in the package's import hooks runs.

What this looks like in a real compromise

Most npm supply-chain incidents have a window: from published to unpublished is hours to a few days. If you weren't installing during that window, you're fine — unless the malicious version is still cached somewhere. Stale node_modules is one of those somewheres. Your laptop's npm cache (~/.npm/_cacache) is another. A reused Docker layer in your local cache is a third.

The defense isn't to never have side projects. It's to make sure when those projects do come back to life — when you cd in, run a script, or do a fresh install — the supply-chain check fires.

The cleanup vs. the prevention

You could rm -rf */node_modules across your code directory once a quarter. Honestly, do that anyway — it'll save you a hundred GB and force a fresh install when you next touch each project.

But the real fix is making the fresh install safe. If npm install for a six-month-dormant project goes through a gate that re-scores every dependency at install time, you don't have to remember which projects have rotted. You just cd, run the install, and trust that anything dangerous gets refused at the registry layer before it lands.

Two minutes, once per machine

veln onboarding
veln wrapper on

After that, every reactivation of an old project — every npm install you run after months of dormancy — goes through the same check as a fresh project. You don't have to maintain the graveyard. You just have to be safe when you visit it.