TL;DR: Every npm package your AI installs brings along its own dependencies — and those bring more. A single npm install can pull in hundreds of packages written by strangers. Dependency scanning automatically checks all of those packages for known security vulnerabilities, malicious code, and suspicious behavior. Without it, you're trusting your app's security to people you've never met. Tools like npm audit, Snyk, Socket.dev, and GitHub Dependabot do this checking for you — and most are free.

Why AI Coders Need This

When you build with Cursor or Claude, your AI doesn't vet packages before installing them. It doesn't check download counts. It doesn't look at when the package was last updated. It doesn't read security advisories. It just installs whatever solves the immediate problem.

That's usually fine. Most packages are legitimate. But "usually fine" isn't a security strategy.

In March 2026, the popular AI framework LiteLLM was compromised — twice. Attackers gained access to the package's distribution pipeline and published versions containing malicious code that exfiltrated API keys and environment variables. Thousands of developers who ran pip install litellm unknowingly installed a backdoor. If you had dependency scanning in place, your tools would have flagged the suspicious new version within hours. Without it, you'd have had no idea until someone noticed your OpenAI bill skyrocketing.

This isn't theoretical. Supply chain attacks increased 742% between 2019 and 2025, according to Sonatype's State of the Software Supply Chain report. The npm registry alone sees dozens of malicious packages published every week. And AI coders are disproportionately vulnerable because AI installs packages fast, often, and without hesitation.

⚠️ The LiteLLM Wake-Up Call

LiteLLM is used by thousands of AI-enabled developers to proxy requests across multiple LLM providers. When it was compromised in March 2026, the malicious version looked identical to the legitimate one — same name, same functionality, plus hidden code that stole API keys. This is what a modern supply chain attack looks like: invisible until the damage is done.

The Supply Chain Problem

Here's what actually happens when you run npm install express:

You run: npm install express

What you think happens:
  You → install express → done ✅

What actually happens:
  You → install express
    express → depends on 30 packages
      Those 30 → depend on 65 MORE packages
        Those 65 → depend on even more...

  Total: 1 command installs 50-80+ packages

Your node_modules folder now contains code written by
dozens of different maintainers across the world.

This is the software supply chain. Just like a physical supply chain — where a car manufacturer depends on tire suppliers who depend on rubber suppliers — your app depends on packages that depend on packages that depend on packages.

And just like a physical supply chain, a problem at any level cascades up to you.

Let's make this concrete with a real-world example:

Your Next.js app
  └── next (framework)
        └── webpack (bundler)
              └── watchpack
                    └── chokidar (file watcher)
                          └── fsevents (native module)

You never installed chokidar. You've never heard of it.
But if chokidar gets compromised, YOUR app is compromised.

These are called transitive dependencies — packages you never chose, never reviewed, and probably don't know exist. In a typical AI-built project, your direct dependencies (the ones you or AI explicitly installed) are maybe 15-30 packages. But your total dependency tree — including transitive dependencies — can be 500 to 1,500+ packages.

Dependency scanning checks all of them. Not just the packages you know about — all of them.

Real Scenario: AI Installed a Vulnerable Package

You asked your AI to add image processing to your app. It ran:

npm install sharp

Sharp is a legitimate, popular image processing library. Over 50 million weekly downloads. But let's say the version AI installed — the latest at the time — depends on libvips, and a specific version of libvips has a known buffer overflow vulnerability (CVE-2023-XXXX) that allows remote code execution if a user uploads a maliciously crafted image.

You didn't know this. AI didn't know this. Your app works perfectly. But every image upload is a potential attack vector.

Here's what happens when you run a dependency scan:

$ npm audit

found 1 vulnerability

  high   Buffer overflow in libvips via sharp
         Package: sharp
         Dependency of: sharp
         Path: sharp > @img/sharp-darwin-arm64
         More info: https://github.com/advisories/GHSA-xxxx-xxxx

  Fix available: npm audit fix
  (updates sharp from 0.32.6 to 0.33.2)

One command. Found the problem. Told you how to fix it. That's dependency scanning.

Without the scan, you'd find out about this vulnerability when a security researcher reports it, when your hosting provider flags it, or — worst case — when an attacker exploits it.

How to Scan Your Dependencies

There are four major tools for dependency scanning, ranging from built-in and free to enterprise-grade. Here's how they compare:

ToolCostWhat It CatchesSetup EffortBest For
npm audit Free (built-in) Known vulnerabilities Zero — already installed Quick checks, beginners
GitHub Dependabot Free Vulnerabilities + outdated deps Enable in repo settings Automated PRs with fixes
Snyk Free tier / paid Vulnerabilities + license issues Sign up + connect repo Deeper analysis, CI/CD integration
Socket.dev Free tier / paid Malicious packages + suspicious behavior Sign up + install GitHub app Catching supply chain attacks

npm audit — Start Here

You already have this. It came with npm. Just run it:

# Check for known vulnerabilities
npm audit

# Automatically fix what can be fixed safely
npm audit fix

# See what would change without actually changing it
npm audit fix --dry-run

# Force fixes even if they include major version bumps (risky)
npm audit fix --force

Pro tip: Run npm audit after every npm install your AI does. Make it a habit.

GitHub Dependabot — Set It and Forget It

If your code is on GitHub, enable Dependabot. It scans your dependencies automatically and creates pull requests to update vulnerable packages. You don't need to remember to scan — it does it for you.

To enable it, create a file at .github/dependabot.yml:

version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 10

That's it. Dependabot will now check your npm dependencies every week and open PRs for any that have security updates.

Socket.dev — The Supply Chain Specialist

Socket.dev does something different from the others: it analyzes what packages actually do, not just whether they have known vulnerabilities. It looks for suspicious patterns like:

  • Packages that access the network when they shouldn't
  • Packages that read environment variables (where your API keys live)
  • Packages that execute shell commands during installation
  • Packages that were just published by a new maintainer (possible account takeover)
  • Packages with obfuscated or minified source code

This is exactly the kind of behavior that flagged the LiteLLM compromise. The malicious version was reading environment variables and sending them to an external server — behavior Socket.dev would flag immediately.

Snyk — The Comprehensive Option

Snyk combines vulnerability scanning with license checking, fix suggestions, and CI/CD integration. It's the most feature-rich option and has a generous free tier for open-source projects. If you're serious about security and want one tool that does everything, Snyk is the answer.

What AI Gets Wrong About Dependencies

⚠️ AI Failure Mode #1: Installing Abandoned Packages

AI doesn't check when a package was last updated. It might install a package that hasn't been maintained in three years — meaning known vulnerabilities will never be patched. Fix: After AI installs a package, check its npm page. If the last publish was over a year ago and it has open security issues, ask AI for an actively maintained alternative.

⚠️ AI Failure Mode #2: Not Checking Download Counts

AI might suggest a package with 200 weekly downloads instead of a well-known alternative with 2 million. Low-download packages are more likely to be malicious, abandoned, or poorly tested. Fix: "Is there a more popular package that does the same thing? I want something with at least 100K weekly downloads."

⚠️ AI Failure Mode #3: Ignoring Audit Warnings

When AI runs npm install and the output shows "found 5 vulnerabilities (2 high)," AI often proceeds without addressing them. It treats audit warnings as noise. Fix: After every install, tell your AI: "Run npm audit and fix any high or critical vulnerabilities before continuing."

⚠️ AI Failure Mode #4: Pinning Exact Versions Without Updates

AI sometimes pins exact package versions ("express": "4.18.2" instead of "express": "^4.18.2"). This prevents minor and patch updates — including security patches — from being installed. Your project freezes in time while vulnerabilities accumulate. Fix: Use caret ranges (^) for most dependencies and let patch/minor updates flow in. Only pin versions when you have a specific compatibility reason.

⚠️ AI Failure Mode #5: Trusting Every Package Suggestion

AI sometimes hallucinates package names or suggests packages that are typosquats — malicious packages with names similar to popular ones (like expres instead of express). Fix: Before running npm install anything, verify the package name on npmjs.com. Check: Is the name spelled correctly? Does it have real downloads? Is there a GitHub repo linked?

What to Do When You Find a Vulnerability

You ran npm audit and it found something. Now what? Here's your decision tree:

npm audit found a vulnerability
│
├── Is it Critical or High severity?
│   ├── YES → Fix it now
│   │   ├── Does `npm audit fix` resolve it?
│   │   │   ├── YES → Run it. Done. ✅
│   │   │   └── NO → Is there a newer version of the package?
│   │   │       ├── YES → Update manually: npm install package@latest
│   │   │       └── NO → Is there an alternative package?
│   │   │           ├── YES → Switch to it. Ask AI to help migrate.
│   │   │           └── NO → Does the vulnerability affect your use case?
│   │   │               ├── YES → Implement a workaround or remove the feature
│   │   │               └── NO → Document it, monitor for fix, revisit weekly
│   └── NO (Low or Moderate) →
│       ├── Does `npm audit fix` resolve it easily?
│       │   ├── YES → Fix it. Why not.
│       │   └── NO → Add to your backlog. Check monthly.
│
└── Is it in a dev dependency only?
    └── YES → Lower priority (doesn't ship to production)
        But still fix when convenient — compromised dev tools
        can inject malicious code during your build process.

The Most Important Thing: Don't panic. Not every vulnerability is exploitable in your specific app. A vulnerability in a function you never call can't hurt you. But you need to know it's there — that's what scanning gives you. The knowledge to make an informed decision instead of being blindsided.

Setting Up Continuous Scanning (10 Minutes)

The best dependency scanning is the kind you don't have to remember to do. Here's a GitHub Actions workflow that scans your dependencies on every push and every week:

# .github/workflows/security-scan.yml
name: Dependency Security Scan

on:
  push:
    branches: [main]
    paths: ['package.json', 'package-lock.json']
  schedule:
    - cron: '0 9 * * 1'  # Every Monday at 9 AM
  workflow_dispatch:  # Manual trigger

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - run: npm ci

      - name: Run security audit
        run: npm audit --audit-level=high
        # Fails the build if high/critical vulnerabilities found

      - name: Check for outdated packages
        run: npm outdated || true
        # Informational — doesn't fail the build

This gives you three layers of protection:

  • On push: Catches vulnerabilities introduced by new package installs
  • Weekly schedule: Catches newly discovered vulnerabilities in existing packages
  • Manual trigger: Run anytime you want a check

Combine this with Dependabot for automatic fix PRs, and you have a security setup that most professional development teams would envy — in 10 minutes of setup.

The 5-Minute Dependency Security Checklist

Do this every time AI installs new packages:

Quick Check Routine:

  1. Run npm audit — are there any high/critical vulnerabilities?
  2. Check the package on npmjs.com — does it have real downloads? Recent updates? A linked GitHub repo?
  3. Look at your package.json diff — did AI add anything you didn't ask for?
  4. Run npm audit fix if issues were found
  5. Commit your package-lock.json — this locks your dependency tree so everyone gets the same versions

This takes 5 minutes and catches 90% of dependency security issues.

Frequently Asked Questions

At minimum, every time you add a new package and before every deployment. Ideally, set up automated scanning with GitHub Dependabot or Snyk that runs continuously. New vulnerabilities are discovered daily in existing packages — a package that was safe last week might have a known exploit today.

npm audit is a good starting point but not comprehensive. It only checks known vulnerabilities in the npm advisory database. It misses malicious packages that haven't been reported yet, typosquatting attacks, and packages with suspicious behavior patterns. For real protection, combine npm audit with a tool like Socket.dev that analyzes actual package behavior.

First, check if the vulnerability actually affects your use case — many vulnerabilities are in code paths you never trigger. If it does affect you, look for an alternative package that does the same thing. If there's no alternative, pin the current version, monitor for a fix, and implement a workaround that avoids the vulnerable code path. Document your decision so future-you knows why.

Yes, but verify what it does. AI is great at running npm audit fix, updating package versions, and finding alternative packages. But AI can also introduce new vulnerabilities by upgrading to untested versions or suggesting obscure replacement packages. Always review the changes AI makes to your package.json and test after updates.

A vulnerability is an accidental security flaw in legitimate software — the maintainer made a mistake. A malicious package is intentionally designed to steal data, mine cryptocurrency, or compromise your system. Dependency scanning catches both, but they require different tools: npm audit finds known vulnerabilities, while Socket.dev and Snyk detect suspicious behavior patterns that indicate malicious intent.