# npm Package Intel — Downloads, Dependents, Health, Search (`yadroo/npm-package-intel`) Actor

npm package intelligence for AI agents and due diligence: versions and dist-tags, weekly/monthly/daily downloads, dependents, publish cadence, deprecation, license, repository, TypeScript/ESM/provenance flags, dependencies and size. Registry search by keyword, author or scope.

- **URL**: https://apify.com/yadroo/npm-package-intel.md
- **Developed by:** [Samat Makatov](https://apify.com/yadroo) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 result items

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## npm Package Intel — downloads, dependents, maintenance health, registry search

One clean JSON per npm package: latest version and dist-tags, weekly/monthly/yearly downloads, daily download series,
number of dependents, publish cadence (releases in the last 90/365 days, days since last publish), deprecation status,
license, repository, TypeScript/ESM/provenance flags, dependency counts and maps, package size — plus a **registry search
mode** to discover packages by keyword, author, maintainer or scope. Built for dependency due diligence, competitor
tracking and developer-tool lead generation. No API key, no proxy, no browser.

### Use cases

- **Dependency due diligence** — before adopting a library: is it maintained, deprecated, single-maintainer, published with provenance, how big is it?
- **Supply-chain monitoring** — run daily on your `package.json` list; alert when `deprecated`, `maintainers`, `lastPublisher` or `integrity` changes.
- **Competitor tracking** — weekly downloads, dependents and release cadence of rival SDKs side by side.
- **Ecosystem research** — `searchQueries: ["keywords:mcp"]` ranked by popularity → who ships MCP servers, how fast the space grows.
- **Developer-tool lead generation** — find maintainers of packages in your niche (`author:`, `maintainer:` qualifiers) and their repos/homepages.
- **Migration analytics** — `includeVersionDownloads` shows how much traffic still sits on old majors of your own package.

### Input

| Field | Type | Default | Notes / allowed values |
|---|---|---|---|
| `packages` | string\[] | `[]` | Package names, scoped or not. npmjs.com URLs and `name@version` are normalized; latest version is always reported. |
| `searchQueries` | string\[] | `[]` | Free text for `registry.npmjs.org/-/v1/search`. Qualifiers: see Reference. |
| `searchMaxItems` | integer | `25` | 1–10 000 per query (registry paginates 250/request, stops at offset 10 000). |
| `searchQuality` / `searchPopularity` / `searchMaintenance` | integer 0–100 | registry default | Ranking weights (sent as 0.0–1.0). |
| `searchExcludeUnstable` | boolean | `false` | Appends `not:unstable` (drops 0.x). |
| `searchExcludeInsecure` | boolean | `false` | Appends `not:insecure`. |
| `searchHydrate` | boolean | `false` | Fetch the full profile for each search hit (2–4 requests per package). |
| `versionsLimit` | integer | `10` | 0–100 recent versions in `recentVersions`. |
| `includeDependencies` | boolean | `true` | Include `dependencies` / `peerDependencies` / `optionalDependencies` maps. |
| `includeDependents` | boolean | `true` | Adds `dependents`, `searchScore`, `insecure` (1 extra request per package). |
| `includeBundleSize` | boolean | `false` | Adds `bundle` from bundlephobia.com (unofficial, slow, front-end libs only). |
| `includeDownloadsYear` | boolean | `false` | Adds `downloadsYear`. |
| `downloadRange` | string | `""` | `last-day`, `last-week`, `last-month`, `last-year` or `YYYY-MM-DD:YYYY-MM-DD` (max 18 months, data from 2015-01-10). Adds `downloadsDaily` + `downloadsRange`. |
| `includeVersionDownloads` | boolean | `false` | Adds `versionDownloads` (top 5 versions last week, latest / latest-major share). |
| `fields` | string\[] | `[]` | Keep only these top-level fields (`id` and `name` always kept). |

At least one of `packages` or `searchQueries` is required. Invalid `downloadRange` fails the run immediately with a message.

### Reference

#### Search qualifiers (registry.npmjs.org `-/v1/search`)

| Qualifier | Meaning | Example |
|---|---|---|
| `keywords:a,b` | package lists these keywords | `keywords:mcp,agent` |
| `author:name` | npm user is the author | `author:sindresorhus` |
| `maintainer:name` | npm user is a maintainer | `maintainer:apify` |
| `scope:name` | packages under `@name/` | `scope:modelcontextprotocol` |
| `not:unstable` / `is:unstable` | exclude / only versions `< 1.0.0` | `hono not:unstable` |
| `not:insecure` / `is:insecure` | exclude / only packages flagged insecure | `keywords:auth not:insecure` |
| `boost-exact:false` | do not boost exact name matches | `request boost-exact:false` |

Free text matches name, description, keywords and README.

#### Download periods (api.npmjs.org)

| Value | Window |
|---|---|
| `last-day` | previous UTC day |
| `last-week` | last 7 full days |
| `last-month` | last 30 full days |
| `last-year` | last 365 full days |
| `YYYY-MM-DD:YYYY-MM-DD` | any custom span up to 18 months |

Weekly and monthly totals are fetched in bulk (128 unscoped names per request); scoped packages (`@scope/name`) are
fetched one by one because the bulk endpoint does not support them. Counts are download *requests*, including CI and mirrors.

#### Score fields (`searchScore`)

`quality`, `popularity`, `maintenance` are 0–1 as computed by the npm search index; `final` is the weighted score used
for ranking. Deprecated packages are demoted to the bottom of search results, so their `dependents` is usually `null`.

### Examples

**Vet the dependencies of a project**

```json
{ "packages": ["hono", "zod", "@modelcontextprotocol/sdk", "request"], "includeVersionDownloads": true }
```

**Daily supply-chain watch — only the fields that matter, cheap**

```json
{ "packages": ["express", "lodash", "axios"], "includeDependencies": false, "includeDependents": false,
  "fields": ["version", "lastPublish", "lastPublisher", "maintainers", "deprecated", "integrity", "hasProvenance"] }
```

**Map the MCP ecosystem by popularity**

```json
{ "searchQueries": ["keywords:mcp"], "searchMaxItems": 200, "searchPopularity": 100, "searchQuality": 0,
  "searchMaintenance": 0, "searchExcludeUnstable": true }
```

**Leads: maintainers publishing in a niche, with repos and homepages**

```json
{ "searchQueries": ["keywords:x402", "keywords:agent-payments"], "searchMaxItems": 50, "searchHydrate": true,
  "fields": ["query", "version", "maintainers", "author", "repository", "homepage", "downloadsWeek", "releasesLast90d"] }
```

**Download trend for a pricing/board deck**

```json
{ "packages": ["hono"], "downloadRange": "2026-03-01:2026-09-01", "includeDownloadsYear": true }
```

### Output

One item per package. Trimmed real example (`hono`):

```json
{
  "id": "hono", "name": "hono", "scope": null, "version": "4.13.7",
  "distTags": { "latest": "4.13.7", "next": "4.5.0-rc.2" },
  "description": "Web framework built on Web Standards", "license": "MIT",
  "homepage": "https://hono.dev", "repository": "https://github.com/honojs/hono",
  "npmUrl": "https://www.npmjs.com/package/hono",
  "author": "Yusuke Wada", "maintainers": ["yusukebe"], "maintainersCount": 1, "lastPublisher": "GitHub Actions",
  "created": "2021-12-14T20:08:48.105Z", "lastPublish": "2026-09-04T19:18:07.204Z",
  "daysSinceLastPublish": 8, "lastAnyPublish": "2026-09-04T19:18:07.204Z", "daysSinceAnyPublish": 8, "releasesLast90d": 17, "releasesLast365d": 68, "versionsCount": 449,
  "recentVersions": [{ "version": "4.13.7", "publishedAt": "2026-09-04T19:18:07.204Z" }],
  "deprecated": null, "deprecatedAllVersions": false, "deprecatedVersionsCount": 0,
  "hasTypes": true, "isEsm": true, "hasExports": true, "hasBin": false, "engines": { "node": ">=16.9.0" },
  "deps": 0, "peerDeps": 0, "optionalDeps": 0, "devDeps": 24, "dependencies": {},
  "unpackedSize": 1391192, "fileCount": 568, "hasProvenance": true,
  "downloadsWeek": 48737764, "downloadsMonth": 217131876, "dependents": 5566,
  "searchScore": { "final": 2214.9, "quality": 1, "popularity": 1, "maintenance": 1 }, "insecure": false,
  "sourceUrl": "https://registry.npmjs.org/hono", "fetchedAt": "2026-09-12T23:26:11.402Z"
}
```

| Field | Type | Description |
|---|---|---|
| `id`, `name`, `scope` | string | Stable id = package name; `scope` like `@x402` or `null`. |
| `version`, `distTags` | string, object | Latest version and all dist-tags (`latest`, `next`, `beta`…). |
| `description`, `license`, `homepage`, `repository`, `bugs`, `npmUrl`, `keywords` | — | Repository URL normalized to `https://…` (git+, ssh, shorthand handled). |
| `author`, `maintainers`, `maintainersCount`, `lastPublisher` | — | `lastPublisher` = npm user (or "GitHub Actions" for trusted publishing) who pushed the latest version. |
| `created`, `modified`, `firstPublish` | ISO | Timeline (`modified` also moves on metadata-only changes). |
| `lastPublish`, `daysSinceLastPublish` | ISO / number | Release date of the `latest` dist-tag version and days since then — "how old is what `npm install` gives you". |
| `lastAnyPublish`, `daysSinceAnyPublish` | ISO / number | Newest publish of **any** version, incl. backports to older majors and prereleases (express 4.x patches, `next` tags) — "is anyone still releasing". The two differ for packages that maintain several lines. |
| `releasesLast90d`, `releasesLast365d`, `versionsCount`, `recentVersions` | number / array | Publish cadence. Hundreds of releases per 90 days is a spam/auto-publish signal. |
| `deprecated`, `deprecatedAllVersions`, `deprecatedVersionsCount` | string|null, boolean, number | Deprecation message on the latest version vs. whole-package deprecation. |
| `hasTypes`, `isEsm`, `hasExports`, `hasBin`, `engines`, `funding` | — | Packaging facts of the latest version. |
| `deps`, `peerDeps`, `optionalDeps`, `devDeps`, `dependencies`, `peerDependencies`, `optionalDependencies` | numbers / maps | Depth-1 dependency tree of the latest version. |
| `unpackedSize`, `fileCount`, `tarball`, `integrity`, `hasProvenance`, `provenanceUrl` | — | Artifact facts; `integrity` changing without a version bump is a red flag. |
| `downloadsWeek`, `downloadsMonth`, `downloadsYear`, `downloadsRange`, `downloadsDaily` | number / object / array | From api.npmjs.org; `null` when npm has no stats yet. |
| `versionDownloads` | object | `{ total, latestShare, latestMajorShare, top[] }` for last week. |
| `dependents`, `searchScore`, `insecure`, `unstable` | — | From the search index (`null` if the package is not found by its own name). |
| `bundle` | object | `{ size, gzip, dependencyCount, version }` from bundlephobia, optional. |
| `query`, `hydrated`, `hydrateError` | — | Present for items that came from `searchQueries`. |
| `sourceUrl`, `fetchedAt` | string | Registry document URL and UTC timestamp. |

Search-mode items without `searchHydrate` carry the subset available in the index: name, version, description, license,
links, maintainers, `lastPublish`, weekly/monthly downloads, `dependents`, `searchScore`, `insecure`, `unstable`, `hydrated: false`.

### Use it from code / agents

**Apify API (curl)**

```bash
curl -X POST "https://api.apify.com/v2/acts/yadroo~npm-package-intel/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"packages":["hono","@x402/hono"],"includeVersionDownloads":true}'
```

**JavaScript (`apify-client`)**

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('yadroo/npm-package-intel').call({ searchQueries: ['keywords:mcp'], searchMaxItems: 100 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

**Python (`apify-client`)**

```python
from apify_client import ApifyClient
client = ApifyClient(token)
run = client.actor("yadroo/npm-package-intel").call(run_input={"packages": ["requests-like", "hono"]})
items = client.dataset(run["defaultDatasetId"]).list_items().items
```

**MCP** — add `https://mcp.apify.com` to Claude, Cursor or any MCP client and call the `yadroo/npm-package-intel` tool with the same JSON input.

### Pricing

Pay per event: **$0.001 per run start + $0.002 per dataset item** (package). Packages that are not on the registry or could not be fetched are not items and are not charged — they are listed in the `SUMMARY` record of the default key-value store (`notFound[]`, `errors[{input, error}]`, with counts) and in the run's status message. The run fails only when no package could be fetched at all.
Typical runs: 10 packages ≈ $0.021; a 200-package ecosystem search ≈ $0.401; a daily 50-package watch ≈ $0.101/day.

### Limits & FAQ

- **Rate limits.** The registry and api.npmjs.org have no published quota; the Actor waits ~120 ms between packages, retries 429/5xx three times with backoff, and fails the item (not the run) if a package still cannot be fetched.
- **Freshness.** Metadata is live from the registry. Download counts are aggregated by npm once a day and lag ~24 h; "last-week" ends yesterday (UTC).
- **New packages** have `downloadsWeek: null` with a warning in the log — npm has no stats yet.
- **Dependents** come from the search index; packages that do not show up in the top-20 hits for their own name (typically deprecated ones) get `null`.
- **Bundle size** uses an unofficial bundlephobia endpoint that can take 10–20 s per cold package or fail for native/Node-only packages; it is off by default and never fails the item.
- **Scoped packages** cost one extra download request each (bulk endpoint limitation).
- **What is NOT included:** vulnerability advisories (use `npm audit` / OSV), GitHub stars (use GitHub Repo Intel), install-time dependency tree beyond depth 1.
- **Roadmap:** OSV vulnerability lookup, diff mode against a previous run for change alerts.

***

Made by **Yadroo**. Sibling actors: [GitHub Repo Intel](https://apify.com/yadroo/github-repo-intel) ·
[PyPI Package Intel](https://apify.com/yadroo/pypi-package-intel) · [Hacker News Search](https://apify.com/yadroo/hackernews-search) ·
[Stack Exchange Search](https://apify.com/yadroo/stackexchange-search)

# Actor input Schema

## `packages` (type: `array`):

npm package names, scoped or not (`hono`, `@modelcontextprotocol/sdk`). npmjs.com URLs and `name@version` are accepted and normalized; the latest version is always reported. One dataset item per package; unknown packages produce an item with `error`.

## `searchQueries` (type: `array`):

Free-text searches against registry.npmjs.org (same engine as npmjs.com search). Supports qualifiers: `keywords:mcp`, `author:sindresorhus`, `maintainer:apify`, `scope:apify`, `not:unstable`, `not:insecure`, `is:unstable`, `is:insecure`, `boost-exact:false`. Each query returns up to `searchMaxItems` packages.

## `searchMaxItems` (type: `integer`):

Registry pages are 250 per request; results stop at offset 10 000. Each package returned is a billed item.

## `searchQuality` (type: `integer`):

0–100, sent to the registry as a 0.0–1.0 weight. Quality = tests, README, types, no deprecations. Leave empty for registry defaults.

## `searchPopularity` (type: `integer`):

0–100 weight for downloads/dependents. Set 100 with quality/maintenance 0 to rank strictly by popularity.

## `searchMaintenance` (type: `integer`):

0–100 weight for release/issue activity.

## `searchExcludeUnstable` (type: `boolean`):

Appends `not:unstable` to every search query.

## `searchExcludeInsecure` (type: `boolean`):

Appends `not:insecure` to every search query.

## `searchHydrate` (type: `boolean`):

Fetch the full registry document + download stats for every search hit (2–4 extra requests per package). Off = lightweight items straight from the search index (name, version, weekly/monthly downloads, dependents, score, maintainers, links).

## `versionsLimit` (type: `integer`):

How many most recent versions (with publish dates) to include in `recentVersions`.

## `includeDependencies` (type: `boolean`):

Include `dependencies`, `peerDependencies`, `optionalDependencies` of the latest version (name → range). Counts (`deps`, `peerDeps`, `optionalDeps`, `devDeps`) are always included.

## `includeDependents` (type: `boolean`):

One extra search request per package to get `dependents` (number of packages depending on it), `searchScore` (quality/popularity/maintenance 0–1) and the `insecure` flag.

## `includeBundleSize` (type: `boolean`):

Adds `bundle` {size, gzip, dependencyCount} from bundlephobia.com — unofficial, slow (a cold package can take 10–20 s) and fails for native/server-only packages. Use for front-end libraries only.

## `includeDownloadsYear` (type: `boolean`):

Adds `downloadsYear` (rolling 365 days).

## `downloadRange` (type: `string`):

Adds `downloadsDaily` (one row per day) and `downloadsRange` totals. Accepts `last-day`, `last-week`, `last-month`, `last-year` or a custom `YYYY-MM-DD:YYYY-MM-DD` (max 18 months, data starts 2015-01-10). Empty = off.

## `includeVersionDownloads` (type: `boolean`):

Adds `versionDownloads`: top 5 versions by weekly downloads, share of the latest version and of the latest major line — shows how fast users migrate.

## `fields` (type: `array`):

Keep only the listed top-level fields in each item (`id`, `name`, `error` are always kept). Empty = all fields.

## Actor input object example

```json
{
  "packages": [
    "hono",
    "@x402/hono"
  ],
  "searchQueries": [],
  "searchMaxItems": 25,
  "searchExcludeUnstable": false,
  "searchExcludeInsecure": false,
  "searchHydrate": false,
  "versionsLimit": 10,
  "includeDependencies": true,
  "includeDependents": true,
  "includeBundleSize": false,
  "includeDownloadsYear": false,
  "includeVersionDownloads": false,
  "fields": []
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "packages": [
        "hono",
        "@x402/hono"
    ],
    "searchQueries": [],
    "fields": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("yadroo/npm-package-intel").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "packages": [
        "hono",
        "@x402/hono",
    ],
    "searchQueries": [],
    "fields": [],
}

# Run the Actor and wait for it to finish
run = client.actor("yadroo/npm-package-intel").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "packages": [
    "hono",
    "@x402/hono"
  ],
  "searchQueries": [],
  "fields": []
}' |
apify call yadroo/npm-package-intel --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,yadroo/npm-package-intel"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/WPP6keGdgewj9cq7Q/builds/Lk6wVjff5FDiVMPRE/openapi.json
