# Package Adoption Tracker: npm & PyPI Download Trends (`scrapemint/package-adoption-tracker`) Actor

Keyless download data for npm and PyPI packages: last week against the week before with growth percent, the 30 day total and daily series, plus keyword search across npm ranked by growth to find what is rising in a space. Pay per row.

- **URL**: https://apify.com/scrapemint/package-adoption-tracker.md
- **Developed by:** [Ken M](https://apify.com/scrapemint) (community)
- **Categories:** Developer tools, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 1,000 package rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Package Adoption Tracker: npm & PyPI Download Trends

Keyless **download data** for **npm** and **PyPI** packages. No API key, no account. Stars are vanity and easy to game; installs are what people actually do.

- **Trends** — per package: downloads in the last 7 days, the 7 days before that, the **growth percent** between them, the 30 day total and the daily average. Direction, not just size.
- **Discover** — search npm by keyword, take the highest ranked packages and rank them **by growth**. This answers "what is actually rising in the vector database space", which is a different question from "what has the most stars".
- **History** — the daily download series, one row per package per day, ready to chart.

### Who uses it

- **Engineering leads choosing a dependency** — you are picking something you will live with for years, and a library whose installs are falling is a maintenance problem waiting to happen.
- **VCs and analysts** — open source traction is a leading indicator, and download growth is the cleanest public measure of it.
- **Developer tool marketers** — track your own adoption against competitors, weekly, on a schedule.
- **Package maintainers** — see your own trend without wiring up analytics.

Pairs with our [GitHub Trending Scraper](https://apify.com/scrapemint/github-trending-scraper) for what is being starred and the [Hugging Face AI Models Scraper](https://apify.com/scrapemint/huggingface-ai-models-scraper) for model adoption.

### Input

| Field | Description |
|-------|-------------|
| `mode` | `trends`, `discover`, or `history`. |
| `registry` | `npm` (all three modes) or `pypi` (trends only). |
| `packages` | Names to track. Scoped npm names like `@langchain/core` are handled. |
| `searchQuery` | What space to search, in discover mode. |
| `searchLimit` | How many top results to pull download data for. |
| `minWeeklyDownloads` | Drop abandoned and toy packages. |
| `includeMetadata` | Add version, license, repository and last publish date. |
| `maxRows` | Row cap per run. |

### Output

- **Trends and discover**: `packageName`, `registry`, `scoped`, `lastWeek`, `priorWeek`, `growthPercent`, `last30Days`, `averagePerDay`, `windowStart`, `windowEnd`, `url`, plus `searchScore` and `searchRank` in discover mode and `latestVersion`, `license`, `repository`, `lastPublishedAt`, `versionCount` when metadata is on.
- **History**: `packageName`, `day`, `downloads`.
- **PyPI trends**: `packageName`, `lastDay`, `lastWeek`, `lastMonth`, `url`.

### Notes on the data

- **Growth is measured against the registry's own returned days, not against today's date.** npm publishes with a lag of several days and the lag moves, so the series is sliced into its last 7 and prior 7 buckets from whatever window came back. `windowStart` and `windowEnd` tell you exactly what was compared.
- **npm bulk lookups reject scoped packages.** `@scope/name` is fetched individually and merged back in, so a mixed list works, it is just slightly slower per scoped name.
- **A misspelled npm package is not an error.** The registry returns a null value inside an otherwise successful response, so unknown names are logged and skipped rather than silently counted as zero.
- **PyPI is trends only.** It publishes no keyless search, and pypistats serves totals rather than a daily series, so PyPI rows carry no `growthPercent` and cannot be charted. It also rate limits hard, one package per request with spacing.
- Download counts include continuous integration and mirror traffic. They measure activity, not distinct humans, and that is true of every download figure anyone quotes.

### Pricing

Pay per event: **$0.003 per row**. The first 2 rows of every run are free.

Data sources: npm registry and downloads API, pypistats.org.

# Actor input Schema

## `mode` (type: `string`):

trends = per package downloads with week over week growth. discover = search npm by keyword and rank the results by growth, to find what is rising in a space. history = the daily download series, one row per package per day.

## `registry` (type: `string`):

npm supports all three modes. PyPI supports trends only, because it publishes no keyless search and no daily series.

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

Package names to track, e.g. langchain, @langchain/core, openai. Scoped npm names starting with @ are handled. Ignored in discover mode.

## `searchQuery` (type: `string`):

What space to search npm for, e.g. vector database, ai agent, react charts.

## `searchLimit` (type: `integer`):

How many of the highest ranked search results to pull download data for.

## `minWeeklyDownloads` (type: `integer`):

Drop packages below this many downloads in the last week. The main filter for cutting abandoned and toy packages out of a discover run. 0 = keep everything.

## `includeMetadata` (type: `boolean`):

Add latest version, license, repository, version count and last publish date from the npm registry. One extra request per package, so it is off by default. Discover mode already includes this from the search result.

## `maxRows` (type: `integer`):

Cap on rows returned. Controls total cost. History mode returns about 30 rows per package.

## Actor input object example

```json
{
  "mode": "trends",
  "registry": "npm",
  "packages": [
    "langchain",
    "@langchain/core",
    "openai",
    "llamaindex",
    "ai"
  ],
  "searchQuery": "vector database",
  "searchLimit": 20,
  "minWeeklyDownloads": 0,
  "includeMetadata": false,
  "maxRows": 200
}
```

# 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": [
        "langchain",
        "@langchain/core",
        "openai",
        "llamaindex",
        "ai"
    ],
    "searchQuery": "vector database"
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapemint/package-adoption-tracker").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": [
        "langchain",
        "@langchain/core",
        "openai",
        "llamaindex",
        "ai",
    ],
    "searchQuery": "vector database",
}

# Run the Actor and wait for it to finish
run = client.actor("scrapemint/package-adoption-tracker").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": [
    "langchain",
    "@langchain/core",
    "openai",
    "llamaindex",
    "ai"
  ],
  "searchQuery": "vector database"
}' |
apify call scrapemint/package-adoption-tracker --silent --output-dataset

```

## MCP server setup

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

```

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/AlGa2HznDjVktXEF1/builds/doxsQDZs5bNBGldD1/openapi.json
