Developer tools
NPM Package Scraper — npm metadata api
Pull rich metadata for any NPM package via the npm registry API — current version, dependencies, weekly downloads, repo URL, license, keywords, README excerpt, deprecation flag — export to JSON or CSV. Free npm registry + downloads API, no key required.
Free Apify credit covers a first run. No credit card to try.
What this Actor scrapes
The NPM registry exposes a JSON endpoint at registry.npmjs.org/<package> for every published package, plus a separate download-count API at api.npmjs.org/downloads/point/last-week/<pkg>. This Actor accepts a list of package names (including scoped packages like @apify/sdk), fans them out in parallel, merges both API responses, and writes one clean structured row per package. Think of it as a production-grade npm metadata api wrapper — no auth tokens, no manual pagination, no stitching two endpoints together yourself.
What we handle for you
- Parallel bulk lookup — configurable concurrency (default 8) across the registry + downloads APIs; process hundreds of packages in a single run.
- Scoped package support —
@scope/nameform works natively, no URL-encoding gymnastics required. - Weekly download counts — optional merge with the NPM downloads API (one extra request per package, toggleable).
- Deprecation detection — surfaces the full deprecation message when a version is marked deprecated, so your audit pipeline catches it automatically.
- Full dependency maps —
dependencies,devDependencies, andpeerDependenciesas structured objects, not raw strings. - Structured, validated output — Pydantic-validated rows with ISO-8601 timestamps and stable field names; export as JSON, CSV, or Excel from Apify Console in one click.
- 🛡️ Browser fingerprint rotation —
curl-cffireplays real Chrome / Firefox / Safari TLS handshakes so every request looks like a genuine browser, not a Python script. - 🌐 Residential proxy rotation via Apify Proxy — fresh session ID and exit IP on every block so you never burn a single IP.
- 🔁 Retries with exponential backoff on
408 / 429 / 5xx— up to 5 attempts per package,Retry-Afterrespected. - 🧱 Rate-limit-aware pacing — we slow down when the target pushes back instead of getting the run banned.
- 🧊 Clean, typed dataset rows — Pydantic-validated, ISO-8601 timestamps, stable field names, JSON / CSV / Excel export straight from Apify Console.
- 💰 Pay-Per-Event pricing — you pay only for results that land in your dataset. No data, no charge.
Use cases
- Dependency audit — score every package in your
package.jsonfor weekly downloads, license compliance, and deprecation status before merging. - Vendor benchmarking — compare competing libraries side-by-side on download trends, maintenance activity, and known issues.
- Supply-chain monitoring — feed the output into Socket, Snyk, or a custom risk dashboard to catch newly-deprecated dependencies before they ship.
- SDK download leaderboards — track weekly download momentum for your own packages and competitors over time.
- AI / RAG knowledge graphs — seed an LLM index with structured npm metadata api responses for package-aware code assistants.
- Hiring intel — find org members listed as maintainers on widely-used packages to inform developer outreach.
Input
Paste this into the Apify Console, or send it as the run input over the API. Proxy settings are on by default; you rarely need to touch them.
| Field | Type | Required | What it does |
|---|---|---|---|
packages | array | yes | List of NPM package names. Scoped packages are supported (use the literal @scope/name form). |
includeDownloads | boolean | no | Adds last-week download count via the api.npmjs.org downloads API. One extra request per package. |
concurrency | integer | no | Parallel registry requests. |
{
"packages": [
"express",
"react",
"@apify/sdk"
],
"includeDownloads": true,
"concurrency": 8,
"proxyConfiguration": {
"useApifyProxy": true
}
} Output
One row per result, schema-validated before it is written. Export JSON, CSV, Excel or XML from the run, or read it over the API.
nameversiondescriptionhomepagelicenseauthormaintainerskeywordsrepository_urlbugs_urldist_tarballenginesdependenciesdev_dependenciespeer_dependenciesdeprecated
{
"name": "express",
"version": "4.21.2",
"description": "Fast, unopinionated, minimalist web framework",
"license": "MIT",
"maintainers": [
"wesleytodd",
"dougwilson"
],
"keywords": [
"express",
"framework",
"sinatra",
"web",
"rest",
"restful",
"router",
"app"
],
"repository_url": "git+https://github.com/expressjs/express.git",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1"
},
"deprecated": null,
"weekly_downloads": 31000000,
"package_url": "https://www.npmjs.com/package/express",
"published_at": "2024-03-25T14:09:03.000Z",
"scraped_at": "2026-06-01T10:00:00.000Z"
} Pricing
| Event | Price | When |
|---|---|---|
| Actor start | $0.20 | Once per run, covers warm-up and proxy session setup. |
| Result emitted | $0.0015 | Per result written to the dataset. |
You pay only for results that land. Cap any run with maxTotalChargeUsd. See pricing & billing for worked examples.
Limitations
latestdist-tag only — per-version lookup (e.g.express@4.18.0) is not yet supported.- Pre-release tags excluded —
alpha,beta,nextdist-tags are not resolved. - Tarball content not extracted — we return the tarball URL; we do not download or unpack it.
- Downloads API cap — the NPM downloads API hard-caps at 128 packages per bulk call; we fan out automatically, but very large batches will take proportionally longer.
- Private packages — scoped private packages (
@org/internal-pkg) return a 404 from the public registry and are skipped with a log warning.
FAQ
What exactly is the npm metadata api?
https://registry.npmjs.org/<package> as a JSON document with full package metadata — versions, maintainers, dependencies, dist tarballs, and more. A separate endpoint at https://api.npmjs.org/downloads/point/last-week/<pkg> returns download counts. This Actor calls both, merges the responses, and delivers clean structured rows. You get a production-grade npm metadata api pipeline without maintaining the plumbing yourself.Is this an npm registry scraper or an API wrapper?
Are download counts exact?
Can I look up a specific version instead of `latest`?
name@version syntax and we resolve to latest for now. Vote or comment on the Actor's Issues tab to prioritise this.What happens when a package has been unpublished?
Why is the `repository_url` prefixed with `git+`?
git+ prefix if your downstream tool expects a bare HTTPS URL.Can I use this alongside the PyPI Package Scraper?
Ready to run it?
Open the listing on Apify, paste the input above, and watch rows land. If it ever breaks, it is our problem before it is yours.
Related Actors