DepVet / Guides

Check an npm package for malware before you install it

Coding agents and CI scripts run npm install on names from a prompt, a README or memory. A pre-install check turns that into a decision with a reason.

The problem

Supply chain attacks reach you through packages that look ordinary: a compromised release of a real library, a malicious package published under a lookalike name, or an AI-suggested name that does not exist until someone registers it. By the time npm install finishes, install scripts may already have run.

How /check answers it

GET /check?ecosystem=npm&name=...&version=... (also pypi) looks up the exact version in the OSV database and the registry. It returns the vulnerability count and maximum severity, a malware boolean that is true when OSV carries a malicious-package advisory for that version, the license and its risk class, deprecation, and a typosquat hint. Rules combine these into verdict: AVOID for a malware advisory or a critical vulnerability, REVIEW for high or moderate vulnerabilities, a copyleft or unknown license, a deprecated release or a suspicious name, otherwise OK. Reasons are plain strings you can log. A name that does not exist returns 404 with a hint, which catches hallucinated packages before anything is installed. Omit version to check the latest.

Request and response

Example for lodash 4.17.20, an older release with known advisories.

$ curl -i "https://depvet.imac2014ville.workers.dev/check?ecosystem=npm&name=lodash&version=4.17.20"
HTTP/2 402
payment-required: eyJ4NDAyVmVyc2lvbiI6Mi4uLn0=   # base64 JSON: scheme "exact", network eip155:8453,
                                                  # asset USDC, amount 5000 (= $0.005)
# An x402 client signs the payment, then retries with a PAYMENT-SIGNATURE header.

The paid response (sample; advisory counts change as OSV updates):

{
  "ok": true,
  "ecosystem": "npm",
  "name": "lodash",
  "version": "4.17.20",
  "license": "MIT",
  "licenseRisk": "permissive",
  "vulnerabilities": { "count": 5, "maxSeverity": "HIGH", "malware": false },
  "deprecated": false,
  "typosquatSuspect": false,
  "verdict": "REVIEW",
  "reasons": ["2 high-severity vulnerability advisory(ies) affect this version."]
}

JavaScript with @x402/fetch

import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";

const signer = privateKeyToAccount(process.env.PRIVATE_KEY); // wallet holding USDC on Base
const pay = wrapFetchWithPaymentFromConfig(fetch, {
  schemes: [{ network: "eip155:8453", client: new ExactEvmScheme(signer) }],
});
const res = await pay("https://depvet.imac2014ville.workers.dev/check?ecosystem=npm&name=lodash&version=4.17.20");
if (res.status === 404) throw new Error("package does not exist: possible hallucinated name");
const r = await res.json();
if (r.verdict === "AVOID") process.exit(1);

Pricing

/check costs $0.005 per package. The fuller /report (dependency counts, OpenSSF Scorecard, maintenance history) costs $0.02. There is no API key and no account: each request is paid in USDC on Base over x402. Malformed input returns 400 and failed lookups return a non-2xx status, so those are not charged.

Limitations

More guides

Sister services