DEV Community

Alex Spinov
Alex Spinov

Posted on

npm Has a Free Security Advisory API — Find Vulnerable Packages Before They Break Your App

Last month, a popular npm package with 10M+ weekly downloads got compromised. Teams scrambled to check if their projects were affected. Most used npm audit — but that only catches known vulnerabilities in your lockfile.

What if you could programmatically check ANY package for security issues, track its download trends, and monitor its dependency chain — all through free APIs? You can.

Here are 4 npm-related APIs that most developers don't know exist.

1. npm Registry API — Package Metadata Without Auth

The npm registry itself is a CouchDB instance with a public REST API:

// Get full package metadata
const response = await fetch('https://registry.npmjs.org/express');
const data = await response.json();

console.log(`Latest version: ${data['dist-tags'].latest}`);
console.log(`Total versions: ${Object.keys(data.versions).length}`);
console.log(`License: ${data.license}`);
console.log(`Weekly downloads: check api.npmjs.org`);
Enter fullscreen mode Exit fullscreen mode

No API key. No rate limits (be polite). JSON response.

What you can extract:

  • Every version ever published
  • All dependencies and devDependencies for each version
  • Maintainers and their emails
  • Repository URL, homepage, bugs URL
  • Publish dates for every version

2. npm Downloads API — Track Popularity Trends

// Daily downloads for last month
const res = await fetch('https://api.npmjs.org/downloads/point/last-month/express');
const data = await res.json();
console.log(`${data.package}: ${data.downloads.toLocaleString()} downloads last month`);

// Compare packages
const packages = ['express', 'fastify', 'koa', 'hapi'];
for (const pkg of packages) {
    const r = await fetch(`https://api.npmjs.org/downloads/point/last-month/${pkg}`);
    const d = await r.json();
    console.log(`${pkg}: ${d.downloads.toLocaleString()}`);
}
// express:    35,234,567
// fastify:     4,891,234  
// koa:         1,234,567
// hapi:          456,789
Enter fullscreen mode Exit fullscreen mode

Range queries:

// Downloads per day for a specific range
const url = 'https://api.npmjs.org/downloads/range/2025-01-01:2025-03-24/react';
const res = await fetch(url);
const data = await res.json();

// Plot the trend
data.downloads.forEach(d => {
    const bar = '#'.repeat(Math.floor(d.downloads / 500000));
    console.log(`${d.day} | ${bar} ${d.downloads.toLocaleString()}`);
});
Enter fullscreen mode Exit fullscreen mode

3. GitHub Advisory Database API — Security Vulnerabilities

GitHub maintains a free, public advisory database for npm packages:

// Search advisories for a package
const query = `
{
  securityAdvisories(first: 5, orderBy: {field: PUBLISHED_AT, direction: DESC}, ecosystem: NPM) {
    nodes {
      summary
      severity
      publishedAt
      vulnerabilities(first: 3) {
        nodes {
          package { name }
          vulnerableVersionRange
          firstPatchedVersion { identifier }
        }
      }
    }
  }
}`;

// Use via GitHub GraphQL API (needs token for GraphQL, but REST is free)
// Or use the REST endpoint:
const res = await fetch('https://api.github.com/advisories?ecosystem=npm&per_page=5');
const advisories = await res.json();
advisories.forEach(a => {
    console.log(`[${a.severity}] ${a.summary}`);
    console.log(`  Published: ${a.published_at}`);
});
Enter fullscreen mode Exit fullscreen mode

4. Bundlephobia API — Check Package Size

// How much will this package add to your bundle?
const res = await fetch('https://bundlephobia.com/api/size?package=lodash@latest');
const data = await res.json();

console.log(`${data.name}@${data.version}`);
console.log(`  Size: ${(data.size / 1024).toFixed(1)} KB`);
console.log(`  Gzipped: ${(data.gzip / 1024).toFixed(1)} KB`);
console.log(`  Download time (3G): ${data.downloadTime}ms`);
Enter fullscreen mode Exit fullscreen mode

Compare alternatives:

const alternatives = ['lodash', 'underscore', 'ramda', 'remeda'];
for (const pkg of alternatives) {
    const r = await fetch(`https://bundlephobia.com/api/size?package=${pkg}@latest`);
    const d = await r.json();
    console.log(`${pkg}: ${(d.gzip / 1024).toFixed(1)} KB gzipped`);
}
// lodash:      25.2 KB
// underscore:   7.1 KB
// ramda:       12.4 KB
// remeda:       5.8 KB
Enter fullscreen mode Exit fullscreen mode

Putting It All Together: Package Health Check

async function packageHealthCheck(name) {
    console.log(`\n=== Health Check: ${name} ===\n`);

    // 1. Basic metadata
    const meta = await (await fetch(`https://registry.npmjs.org/${name}`)).json();
    const latest = meta['dist-tags'].latest;
    console.log(`Latest: ${latest}`);
    console.log(`Versions: ${Object.keys(meta.versions).length}`);
    console.log(`License: ${meta.license}`);

    // 2. Downloads
    const dl = await (await fetch(`https://api.npmjs.org/downloads/point/last-month/${name}`)).json();
    console.log(`Downloads/month: ${dl.downloads.toLocaleString()}`);

    // 3. Bundle size
    try {
        const size = await (await fetch(`https://bundlephobia.com/api/size?package=${name}@latest`)).json();
        console.log(`Bundle size: ${(size.gzip / 1024).toFixed(1)} KB gzipped`);
    } catch(e) {
        console.log('Bundle size: N/A');
    }

    // 4. Dependencies count
    const deps = meta.versions[latest].dependencies || {};
    console.log(`Dependencies: ${Object.keys(deps).length}`);

    // 5. Last publish date
    const time = meta.time[latest];
    const daysSince = Math.floor((Date.now() - new Date(time)) / 86400000);
    console.log(`Last published: ${time.split('T')[0]} (${daysSince} days ago)`);

    if (daysSince > 365) console.log('  ⚠️  WARNING: Not updated in over a year');
    if (Object.keys(deps).length > 20) console.log('  ⚠️  WARNING: Heavy dependency tree');
}

packageHealthCheck('express');
Enter fullscreen mode Exit fullscreen mode

API Reference

API Base URL Auth Use case
npm Registry registry.npmjs.org None Package metadata, versions, deps
npm Downloads api.npmjs.org None Download counts, trends
GitHub Advisories api.github.com/advisories None (REST) Security vulnerabilities
Bundlephobia bundlephobia.com/api None Bundle size analysis

When These APIs Are Not Enough

  • Private packages: Need npm token for private registry
  • Real-time malware detection: Use Socket.dev or Snyk
  • License compliance: Use FOSSA for enterprise-grade scanning

- NASA Has 5 Free APIs — asteroids, Mars photos, space weather

Do you check your dependencies before installing? What tools do you use? I am curious what the community's stack looks like for supply chain security.

More free tools: 77 Web Scraping Tools & APIs

Have you ever found a vulnerable package in your project? Share your story — the scariest dependency vulnerability you caught. 👇

Top comments (0)