How-To Secure Your npm Dependencies
Why this matters
npm is the
nodejs
3rd party library ecosystem. For better and worse, it is bigger and more technically advanced than most. But because
nodejs
is so ubiquitous on the internet, just from sheer scale it has problems most other programming platforms don’t have to deal with.
It is both a magnet for malicious intent as well as for inexperienced developers and overly ambitious deadlines. Having it all in a big global distribution pipeline like the free npm registry is bound to cause problems. It is a supply side attack mecca.
Below you will find some information about built-in tooling that helps you detecting compromised packages and strategies.
1. Clean up your dependencies
The first thing to reduce vulnerability exposure, as always, is to reduce the amount of code used.
The less code you depend on, the smaller your attack surface.
# detect unused dependencies
npx depcheck
⚠️ Warning: depcheck is not perfect. Always verify manually before removing packages.
2. Eliminate version ranges
An easy thing you can do to reduce supply side attack exposure is to use fixed versions in production. Simply pin a specific package version by removing the
^
from your
package.json
dependency versions.
"dependencies": {
"@raclettejs/core": "0.1.10",
"@raclettejs/workbench": "0.1.10"
},
In raclette, we enforce fixed, audited versions across all
@raclettejs
packages.
Unfortunately just ensuring this for your own packages in the
package.json
is not enough. Almost all packages you can find on npm utilze version ranges, which makes them vulnerable to new bugs and attacks. This is where your
yarn.lock
file helps.
3. Check for updates
There are millions of packages, and tens of millions of new versions each year. By the recursive nature of dependencies, each project quickly ends up with hundreds of packages installed.
This is why checking for updates is critical:
# list outdated packages
yarn outdated
# upgrade everything at once
yarn upgrade --latest
Try to stay on recent versions as this reduces the dependency to packages or sub-packages where security issues had been found or might be found in the future.
4. Audit everything
Due to the sheer amount of packages, security checks aren’t something that can be managed by human diligence alone. Human diligence absolutely must be part of it, but without the help of automated tools, a catastrophic slip is guaranteed within the lifespan of a project.
That’s where audits come in:
yarn npm audit
(Note: for yarn 1 use
yarn audit
)
Incorporate audits into your regular build process, at least before deployments.
Be aware that that only works for known vulnerabilities that had been added to the audit database. Keeping an eye open on tech news sites can give early warnings on problems before they arrive there, and quick
grep
s on your package lock files can be a first step to judge vulnerability.
5. Understand your dependencies
Of course, deciding what to do with the shown information is a different matter. That is still manual human diligence. But at least you have a selection of where to start.
It’s easy when the whole package is compromised. You gotta throw it out.
If only parts are compromised, you have to know how each package is used. Which is good and well for your own code, but can become tedious for your dependencies.
yarn why <package>
This shows you exactly why a package is part of your dependency tree.
6. Lockfiles and discipline
Lockfiles (
package-lock.json
,
yarn.lock
,
pnpm-lock.yaml
) guarantee reproducible builds.
Any updates to them should trigger at least one audit run. Treat lockfile changes as critical, especially in projects that publish packages themselves.
7. Private registry (optional)
A private npm registry where you only provide audited package versions can help. It shields you from short-lived attacks, as long as developers don’t bypass it because it lags too far behind. Maintaining it is a lot of work – and slows down development if under-resourced – but for high-security contexts, it can be worth it.
Quick checklist
-
Run
npx depcheck
-
Remove all
^
from dependencies -
Run
yarn outdated
and upgrade -
Run
yarn why <package>
to verify critical dependencies -
Run
yarn audit --level high
before deployments -
Treat lockfile changes as critical
Conclusion
Nothing we are telling here is new. And the mitigation strategies are also not new. But they are often forgotten until the next attack makes headlines.
With discipline and the right tooling, you can drastically reduce your exposure. This is exactly the approach we follow in raclette – and it has already helped us stay ahead of large-scale incidents.
Published on September 19, 2025