DEV Community

Cover image for Your npm install Is More Dangerous Than You Think — A Practical Dependency Safety Checklist
Robert Adamson
Robert Adamson

Posted on

Your npm install Is More Dangerous Than You Think — A Practical Dependency Safety Checklist

Your npm install Is More Dangerous Than You Think — A Practical Dependency Safety Checklist

We type this command almost without thinking:

npm install
Enter fullscreen mode Exit fullscreen mode

A few seconds later, hundreds — sometimes thousands — of packages appear inside node_modules.

Then we start coding.

But there is something developers often forget:

Installing one npm package does not mean trusting only one package.

You may also be trusting:

  • its dependencies
  • dependencies of those dependencies
  • package maintainers
  • install scripts
  • downloaded artifacts
  • future package updates
  • your lockfile
  • your package registry

Most of the time, everything works perfectly.

But when something goes wrong in the software supply chain, npm install can become a surprisingly powerful attack surface.

So before blindly installing the next package, here is the checklist I think developers should follow.


1. Check the package before installing it

Suppose you need a date library.

Don't immediately do:

npm install some-random-date-package
Enter fullscreen mode Exit fullscreen mode

Spend 30 seconds checking it first.

Look at:

  • npm package page
  • GitHub repository
  • latest release
  • maintenance activity
  • open issues
  • number of dependents
  • package documentation
  • who maintains it

The important question isn't:

Does this package have a lot of downloads?

The better question is:

Do I actually trust this project enough to execute its code inside my application?

A popular package can still become compromised.

And an unpopular package is not automatically dangerous.

You need context.


2. Check the package name carefully

This sounds obvious.

But dependency attacks don't always require sophisticated exploits.

Sometimes they rely on developers installing the wrong package.

Imagine you wanted:

some-package
Enter fullscreen mode Exit fullscreen mode

but accidentally installed:

some-pakage
Enter fullscreen mode Exit fullscreen mode

One missing letter can matter.

Before installing unfamiliar dependencies, check the exact:

package name
publisher
repository
Enter fullscreen mode Exit fullscreen mode

Especially when copying commands from random tutorials, Stack Overflow answers, GitHub issues, or AI-generated code.


3. Understand that packages can execute scripts

This is one of the most important things to understand.

npm supports lifecycle scripts such as:

preinstall
install
postinstall
prepare
Enter fullscreen mode Exit fullscreen mode

These scripts can execute as part of the installation lifecycle. npm documents these lifecycle hooks directly.

For legitimate packages, these scripts might:

  • compile native code
  • download binaries
  • generate files
  • prepare dependencies

But from a security perspective, you should remember:

Installing a package may involve executing code, not simply downloading JavaScript files.

For suspicious or unfamiliar projects, you can investigate package scripts before giving them full trust.

Modern npm versions also provide controls around which dependency install scripts are permitted.


4. Commit your package-lock.json

Your lockfile is not random noise that Git generated.

It matters.

package-lock.json records the exact dependency tree npm resolved.

npm explicitly recommends committing it because it helps developers, deployments, and CI install the same dependency tree.

Without a lockfile, two developers may install slightly different versions depending on when they run:

npm install
Enter fullscreen mode Exit fullscreen mode

So this:

package.json
package-lock.json
Enter fullscreen mode Exit fullscreen mode

should normally live together in your repository.

And if a pull request contains a massive unexpected lockfile change?

Don't automatically approve it.

Look at what changed.


5. Prefer npm ci in CI/CD

For automated environments, I generally don't want my dependency tree quietly changing.

That's where:

npm ci
Enter fullscreen mode Exit fullscreen mode

becomes useful.

npm documents an important difference:

npm ci requires a lockfile and will fail when package.json and the lockfile disagree instead of rewriting the lockfile. It also performs a clean install.

That's exactly what you usually want in CI.

Think of it like this:

Developer machine
npm install

CI / deployment
npm ci
Enter fullscreen mode Exit fullscreen mode

Not a universal rule, but a good default.


6. Actually look at dependency changes in pull requests

Imagine someone changes:

"dependencies": {
  "express": "...",
  "new-library": "..."
}
Enter fullscreen mode Exit fullscreen mode

Most code reviews focus on the application code.

The dependency change gets ignored.

That is backwards.

A new dependency can potentially introduce far more code than the developer wrote in the PR.

GitHub's Dependency Review can show:

  • added dependencies
  • removed dependencies
  • version changes
  • known vulnerabilities
  • package usage information

It can also be enforced in CI so vulnerable dependencies introduced by a pull request can cause the check to fail.

Dependency changes deserve code review too.


7. Run npm audit — but don't treat it like magic

You probably know:

npm audit
Enter fullscreen mode Exit fullscreen mode

It's useful.

But don't think:

0 vulnerabilities
Enter fullscreen mode Exit fullscreen mode

means:

100% secure
Enter fullscreen mode Exit fullscreen mode

Security scanners mostly help you detect known problems.

They cannot guarantee that:

  • a maintainer isn't malicious
  • a package hasn't been compromised in another way
  • your own implementation is secure
  • a vulnerability hasn't been discovered yet

So use auditing as one layer.

Not the entire security strategy.


8. Consider package signature verification

Here's something many npm developers still don't use.

npm supports:

npm audit signatures
Enter fullscreen mode Exit fullscreen mode

According to npm's documentation, this can verify registry signatures and provenance attestations for downloaded packages when supported.

That doesn't mean every developer needs to run it manually before every installation.

But for higher-security environments, package integrity and provenance are becoming increasingly important concepts.

We shouldn't only ask:

What package did I download?

We should increasingly ask:

Where did this package come from, and can I verify it?


9. Don't install a dependency for five lines of code

This is partly a security problem and partly an engineering problem.

Imagine you need:

capitalize a string
Enter fullscreen mode Exit fullscreen mode

Do you really need another dependency?

Every dependency adds something to maintain.

Potentially:

updates
breaking changes
licenses
vulnerabilities
transitive dependencies
supply-chain risk
Enter fullscreen mode Exit fullscreen mode

I'm not saying:

Never use packages.

That would be ridiculous.

The npm ecosystem exists because reusing good software is incredibly valuable.

But there should be a small mental check:

Is adding another dependency worth it?

Sometimes the correct answer is absolutely yes.

Sometimes the function takes five lines.


10. Be careful with abandoned dependencies

A dependency doesn't need to be malicious to become a problem.

Sometimes it simply stops being maintained.

Check:

Last update: 4 years ago
Issues: 237
Pull requests: 48
Maintainers: 1
Enter fullscreen mode Exit fullscreen mode

That doesn't automatically mean you shouldn't use it.

Stable software doesn't need commits every Tuesday.

But if the package sits in a security-sensitive part of your application, maintenance status matters.

Especially for things like:

  • authentication
  • encryption
  • file uploads
  • parsers
  • networking
  • database drivers

11. Don't blindly accept dependency updates

There's another dangerous habit:

Dependabot opened 17 PRs.

Merge.
Merge.
Merge.
Merge.
Enter fullscreen mode Exit fullscreen mode

Updating dependencies is important.

Blindly updating them isn't ideal either.

An update can introduce:

breaking behavior
new dependencies
changed build scripts
new permissions
new vulnerabilities
Enter fullscreen mode Exit fullscreen mode

Review what changed.

For important dependencies, read the release notes.

A green CI check is helpful, but it doesn't understand your entire production environment.


12. Protect your CI environment

Dependency installation becomes much more serious inside CI.

Why?

Because CI might have access to:

NPM_TOKEN
GitHub tokens
cloud credentials
deployment secrets
SSH keys
database URLs
Enter fullscreen mode Exit fullscreen mode

Now imagine running untrusted install scripts in the same environment.

That's a much bigger risk than installing something on an empty test machine.

Good CI design should follow least privilege.

A build that only needs to compile code probably doesn't also need production database credentials.


My practical npm dependency checklist

Before adding an unfamiliar dependency, I now think through something like this:

[ ] Did I verify the exact package name?

[ ] Is the repository legitimate?

[ ] Is the project actively maintained?

[ ] Do I understand why this dependency is needed?

[ ] Does it contain install scripts?

[ ] How many transitive dependencies does it bring?

[ ] Did package-lock.json change unexpectedly?

[ ] Does npm audit report known vulnerabilities?

[ ] Is CI using npm ci?

[ ] Am I exposing unnecessary secrets during installation?

[ ] Do I really need this dependency?
Enter fullscreen mode Exit fullscreen mode

You don't need to spend 30 minutes investigating every package.

But 30 seconds of thought is better than:

npm install random-package
Enter fullscreen mode Exit fullscreen mode

and hoping for the best.


The bigger lesson

Modern applications are not just the code we write.

They're more like:

Your code
+
framework
+
libraries
+
transitive dependencies
+
build tools
+
GitHub Actions
+
cloud infrastructure
Enter fullscreen mode Exit fullscreen mode

A small application can depend on code written by hundreds or thousands of people you've never met.

That's one of open source's greatest strengths.

It's also why dependency security matters.

So no, you shouldn't become afraid of:

npm install
Enter fullscreen mode Exit fullscreen mode

But you should stop thinking of it as:

Download some code.

Think of it as:

Add someone else's software to my trust boundary.

That tiny mindset change can make you a much safer developer.


How carefully do you review a package before installing it?

I'm curious whether your team has a dependency security checklist or mostly relies on automated tools.

Top comments (0)