npm Package Stats & Metadata avatar

npm Package Stats & Metadata

Pricing

$0.40 / 1,000 packages

Go to Apify Store
npm Package Stats & Metadata

npm Package Stats & Metadata

npm package scraper for dependency and package research. Export registry metadata as JSON with optional download totals or daily download records.

Pricing

$0.40 / 1,000 packages

Rating

0.0

(0)

Developer

Grit

Grit

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

13 days ago

Last modified

Share

npm packages scraper returns registry metadata and optional download totals or daily download records for selected packages.

npm packages scraper uses the public source named below and writes its results to the Actor dataset.

Supply package names or official npm URLs, discover packages with registry search, or combine both. Scoped packages are supported. The actor enriches the latest version advertised by the registry and removes duplicate package targets before applying the output cap.

What it returns

Fields vary by result type and optional enrichment. The examples below are from sample_output.json.

Output fieldTypeExample value or excerpt from saved sample
packagestring"grit-npm-package-that-does-not-exist-20261005"
statusstring"error"
versionstring or null"7.0.0"
downloadsinteger or null183020118
downloadStartstring or null"2026-09-28"
downloadEndstring or null"2026-10-04"
dailyDownloadsarray or null[{"day": "2026-09-28", "downloads": 36084906}]
rangeTotalinteger or null183020118
rangeStartstring or null"2026-09-28"
rangeEndstring or null"2026-10-04"
downloadPeriodstring"last-week"
searchQuerystring or null"keywords:validation"
searchScorenumber or null66.08935
searchScoresobject or null{"popularity": 1}
sourceUrlsobject{"metadata": "https://registry.npmjs.org/grit-npm-package-that-does-not-exist-20261005"}
errorsarray[{"stage": "metadata", "message": "npm returned HTTP 404", "httpStatus": 404}]
fetchedAtstring"2026-10-05T12:01:51.644217+00:00"
versionCountinteger15
distTagsobject{"latest": "7.0.0"}
descriptionstring"Returns true if a number or string value is a finite number. Useful for regex matches, parsing, use…
licensestring"MIT"
homepagestring"https://github.com/jonschlinkert/is-number"
repositoryUrlstring"https://github.com/jonschlinkert/is-number"
npmUrlstring"https://www.npmjs.com/package/is-number"
createdAtstring"2014-09-22T01:58:51.592Z"
modifiedAtstring"2023-05-26T16:12:33.057Z"
publishedAtstring"2018-07-04T15:08:58.238Z"
maintainersarray["doowb"]
dependenciesobject{}
dependencyCountinteger0
devDependenciesobject{"ansi": "^0.3.1"}
peerDependenciesobject{}
optionalDependenciesobject{}
enginesobject{"node": ">=0.12.0"}
deprecatednullnull
tarballUrlstring"https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
unpackedSizeinteger9615
FieldsMeaning
package, statusCanonical name and ok / partial / error. A search failure has package=null.
version, versionCount, distTagsLatest tagged version, number of registry versions and tag-to-version map.
description, licenseLatest version description and declared license; not a legal assessment.
npmUrl, homepage, repositoryUrlPublic package and project links. Repository URL removes git+ and a trailing .git.
createdAt, modifiedAt, publishedAtRegistry creation/update times and publication time of the latest version.
maintainersPublished npm maintainer names; emails are omitted.
dependencies, dependencyCountLatest version runtime dependency map and its size.
devDependencies, peerDependencies, optionalDependencies, enginesOther dependency maps and declared runtime requirements.
deprecated, unpackedSize, tarballUrlDeprecation message and latest version distribution metadata, when published.
downloads, downloadStart, downloadEndPoint API total and its inclusive UTC dates; null when omitted/unavailable.
dailyDownloadsRange records as {day, downloads}; null when omitted/unavailable.
rangeTotal, rangeStart, rangeEndSum of returned daily downloads and the range's inclusive dates.
downloadPeriodRequested named period or explicit custom interval.
searchQuery, searchScore, searchScoresSearch query, registry score.final and score.detail for discovered packages.
sourceUrls, fetchedAtRequested official source URLs and row collection timestamp.
errorsStage-specific messages with an optional HTTP status. Missing data is not converted to zero.

Metadata-only failure rows contain the common status/download/provenance fields; registry-specific fields may be absent. Available registry fields may be null or empty maps. A run summary is stored under SUMMARY in the default key-value store.

Input example

{
"packages": ["is-number", "@sindresorhus/is"],
"searchQuery": "keywords:validation",
"downloadMode": "both",
"downloadPeriod": "last-week",
"maxItems": 5,
"concurrency": 3
}
InputDefaultBehavior
packages[]Package names or npmjs.com/package URLs; registry.npmjs.org package URLs also work. URL /v/version suffixes still select latest metadata. Plain name@version input is rejected.
searchQueryemptyOfficial registry full-text search, including npm qualifiers such as keywords:validation. At least packages or a query is required.
downloadModebothboth, point, range, or none.
downloadPeriodlast-weeklast-day, last-week, last-month, last-year, or custom.
startDate, endDateemptyRequired for custom. YYYY-MM-DD; ordered inclusive interval from 2015-01-10 through yesterday UTC, at most 366 days.
maxItems1001–10,000 output rows, including errors. Explicit packages take priority over discovered packages.
concurrency51–20 parallel package workers. Each worker sends one request at a time.

A named download period refers to npm's last available UTC days. In both mode, the daily range is requested with the point response's actual dates so cached aliases do not silently select different weeks. If point data fails, range is requested independently using the input period. Point and range values retain their separate source fields.

Real output example

Excerpt of the is-number row from sample_output.json, collected on 2026-10-05:

{
"package": "is-number",
"status": "ok",
"version": "7.0.0",
"license": "MIT",
"repositoryUrl": "https://github.com/jonschlinkert/is-number",
"downloads": 183020118,
"downloadStart": "2026-09-28",
"downloadEnd": "2026-10-04",
"rangeTotal": 183020118,
"rangeStart": "2026-09-28",
"rangeEnd": "2026-10-04",
"dailyDownloads": [
{
"day": "2026-09-28",
"downloads": 36084906
},
{
"day": "2026-09-29",
"downloads": 36365987
},
{
"day": "2026-09-30",
"downloads": 37177002
},
{
"day": "2026-10-01",
"downloads": 37568034
},
{
"day": "2026-10-02",
"downloads": 0
},
{
"day": "2026-10-03",
"downloads": 18159553
},
{
"day": "2026-10-04",
"downloads": 17664636
}
],
"errors": []
}

The saved sample contains 5 rows: 4 successful packages and one intentionally nonexistent package error. The actor's local measured processing time was 1.979 seconds; this is one local run, not a throughput or cloud guarantee. Receipts: evidence/sample-run-summary.json and evidence/independent-sample-check.json.

Pricing

Proposed package event: $0.0004 per metadata-bearing row ($0.40 per 1,000). Download totals and daily records are included. Partial rows retain registry metadata and are charged once. Invalid inputs, metadata failures and discovery error rows are free. No proposed start fee. Publication and actual billing are pending; see PRICING.md for the current leader comparison and required event configuration. Platform resource fees are separate from this proposed event comparison.

Limits and failure handling

  • Metadata and search come from registry.npmjs.org; downloads come from api.npmjs.org. No npm login, browser automation or proxy is required by this implementation.
  • Per-request timeout is 30 seconds, with a 10-second connect timeout. Transient transport failures, HTTP 429 and HTTP 500/502/503/504 get three attempts with backoff and a bounded numeric Retry-After delay.
  • A malformed or missing package produces an error row. Download failures keep registry metadata as a partial row. Discovery failure produces an error row within the combined cap and keeps explicit packages.
  • An empty search with no matches produces an empty dataset. Large registry documents consume memory; reduce concurrency for packages with many versions. Only latest metadata is emitted; full readmes and version manifests are not returned.
  • Downloads are package totals, not unique users or per-version usage. They are published with a delay and may be revised by npm. Search scores and ordering are the registry's values, not a security or quality guarantee.
  • Output order follows completion order. Deduplication and maxItems apply to the current run. There is no checkpointed continuation after a cloud restart or migration.
  • The package charge budget stops further paid rows. Storage or billing failures fail the run rather than being disguised as npm item errors.

FAQ

What limits output? maxItems counts paid and free rows together; package targets are deduplicated before output.

Do I need a proxy or npm login? No. The actor reads public npm registry and download APIs without a login or configured proxy.

How is it priced? The proposed pay-per-event model charges package for each metadata-bearing package row, including a partial row when downloads fail. Metadata failures and error rows have no custom package charge.

How are rate limits handled? Source requests are retried with bounded backoff, including Retry-After when present. Failed download requests can leave download fields null.

How fresh are package metrics? fetchedAt marks collection. Registry timestamps and the download period describe different source windows; downloads can change with later runs.

Do daily download records cost extra? No. Daily records are nested in the package row and do not create another custom event.

Use with AI agents / MCP

MCP (Model Context Protocol) lets an AI agent call tools. After the owner publishes the actor, expose it through Apify's MCP integration or call it using the Apify API. Give the agent the input example above, then read the Results dataset link. Use status, sourceUrls, fetchedAt and errors to decide whether data is suitable for the agent's task. Keep maxItems small during exploration. This package is an actor; it does not contain its own MCP server.

Local development

Use the project's existing venv; no extra packages were needed. From this actor directory in PowerShell:

New-Item -ItemType Directory -Force storage/key_value_stores/default | Out-Null
Copy-Item example_input.json storage/key_value_stores/default/INPUT.json
$env:APIFY_LOCAL_STORAGE_DIR = "$PWD/storage"
C:/GritWork/earn/.venv/Scripts/python.exe -m src
C:/GritWork/earn/.venv/Scripts/python.exe -m pytest tests -m "not live" -q -p no:cacheprovider
C:/GritWork/earn/.venv/Scripts/python.exe -m pytest tests -m live -q -p no:cacheprovider
apify validate-schema

Dataset rows are written under storage/datasets/default. In the verified local SDK 4.0.2 runs, a new actor process produced a fresh default dataset and preserved INPUT.json. Copy outputs before another local run if you want to retain the previous dataset. Docker uses apify/actor-python:3.12 and installs the pinned runtime dependencies from requirements.txt.

Sources

npm registry API, npm download API, Apify Python SDK. Real response fixtures and their retrieval URLs are under tests/fixtures.