# Dev Trend Radar (`heartsome_stalactite/dev-trend-radar`) Actor

Track which developer topics are gaining momentum across GitHub, Stack Overflow, and npm. Get a weekly ranked trend score with week-over-week change.

- **URL**: https://apify.com/heartsome\_stalactite/dev-trend-radar.md
- **Developed by:** [Aaron](https://apify.com/heartsome_stalactite) (community)
- **Categories:** Developer tools, SEO tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $250.00 / 1,000 scan runs

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

## Dev Trend Radar

Track which developer topics are gaining momentum across GitHub, Stack Overflow, and npm. Get a weekly ranked trend report with a single normalized score per topic.

### What is Dev Trend Radar?

Dev Trend Radar takes a list of tech topics and checks three public developer ecosystems for each one:

- **GitHub** - how many repositories use the topic and how many stars the top repos have
- **Stack Overflow** - how many questions carry the matching tag
- **npm** - how many packages match the keyword and their monthly download counts

It combines those three signals into a single **trend score** for each topic, then ranks your topics from strongest to weakest. The score is normalized, so topics are compared on the same scale instead of raw numbers. The Actor also saves a weekly snapshot so you can see **week-over-week change** on later runs.

It runs without a browser, without proxies, and finishes in seconds. No runtime AI, no scraping behind logins, no CAPTCHAs to deal with.

#### What is it for?

- **Dev tool product managers** who want to see which categories are heating up before competitors notice
- **VC and market analysts** who track developer ecosystems and category growth for investment research
- **OSS sponsorship platforms** that look for communities with rising activity to support

#### Why not just check each site yourself?

You can. But checking GitHub, Stack Overflow, and npm separately for 30 topics every week takes hours and the numbers are not directly comparable. Dev Trend Radar does all three in one run, normalizes the scores, ranks the topics, and tracks the change over time automatically.

***

### Input

Paste a list of topics, then optionally adjust the settings.

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `topics` | array of strings | yes | - | 1 to 100 tech topics in lowercase kebab-case (e.g. `vector-database`, `rust-web-frameworks`) |
| `schedule` | string | no | `weekly` | How the run is bucketed for snapshots. Options: `weekly`, `daily` |
| `growthWindowWeeks` | integer | no | `4` | How many weeks back to compare for week-over-week change |
| `maxTopics` | integer | no | `100` | Cap on topics processed after dedup |
| `stackExchangeSite` | string | no | `stackoverflow` | Which Stack Exchange site to query |

#### Example input

```json
{
    "topics": [
        "vector-database",
        "web-scraping",
        "htmx",
        "drizzle-orm",
        "rust-web-frameworks"
    ],
    "schedule": "weekly",
    "growthWindowWeeks": 4,
    "maxTopics": 30,
    "stackExchangeSite": "stackoverflow"
}
```

#### GitHub rate limits

The free GitHub API allows 10 searches per minute without a token. For runs with more than 30 topics, create a free [GitHub personal access token](https://github.com/settings/tokens) and set it as the `GITHUB_TOKEN` environment variable in your Actor settings. This raises the limit to 30 per minute. Without a token, the Actor still works but runs slower for large topic lists.

***

### Output

Each topic produces one row in the dataset. The Actor also writes a summary object to the key-value store.

#### Example dataset row

```json
{
    "topic": "vector-database",
    "github": {
        "repoCount": 6634,
        "starSumTopN": 583247,
        "topNRepos": 25,
        "retrievedAt": "2026-07-22T16:39:00Z"
    },
    "stackOverflow": {
        "tagCount": 328,
        "growthDelta": null,
        "tagAbsent": false,
        "retrievedAt": "2026-07-22T16:39:00Z"
    },
    "npm": {
        "packageCount": 465,
        "downloadSum": 3817785,
        "retrievedAt": "2026-07-22T16:39:00Z"
    },
    "compositeScore": 0.077,
    "rank": 2,
    "weekOverWeekDelta": null,
    "flags": [],
    "retrievedAt": "2026-07-22T16:39:00Z",
    "snapshotWeek": "2026-W30"
}
```

#### Summary object (OUTPUT key in key-value store)

```json
{
    "radar": [
        { "topic": "web-scraping", "compositeScore": 1.846, "rank": 1, "weekOverWeekDelta": null },
        { "topic": "vector-database", "compositeScore": 0.077, "rank": 2, "weekOverWeekDelta": null }
    ],
    "meta": {
        "snapshotWeek": "2026-W30",
        "processedTopics": 5,
        "skippedTopics": [],
        "invalidTopics": [],
        "degradedSources": [],
        "githubRateLimited": false,
        "priorSnapshotExisted": false,
        "actorVersion": "0.1.0"
    }
}
```

#### What the fields mean

- **`compositeScore`** - The combined trend score. Higher means more activity across all three sources relative to the other topics in your list.
- **`rank`** - Position after sorting by score. Rank 1 is the strongest.
- **`weekOverWeekDelta`** - How much the score changed since the prior snapshot. Null on the first run because there is no baseline yet.
- **`flags`** - Status indicators. Common flags:
  - `github-rate-limited` - GitHub returned a rate limit error (add a token to fix)
  - `so-tag-absent` - The topic has no matching tag on Stack Overflow (this is signal, not an error)
  - `npm-partial-downloads` - Some npm download fetches failed but the rest succeeded
  - `all-sources-degraded` - All three sources failed for this topic (row still emitted with zeros)

If a source is unavailable, the Actor returns a row with zeros and a flag explaining what happened. You always get partial results instead of a failed run.

***

### Pricing

This Actor uses **pay per event** pricing.

| Event | Price | When it fires |
|-------|-------|---------------|
| `radar-scan` | $0.25 | Once per run. Covers up to 30 topics. |
| `extra-topic` | $0.01 | Once per topic beyond 30. |
| `apify-actor-start` | ~$0.00005 | Once per run. Apify covers the first 5 seconds of compute. |

#### Example costs

| Topics per run | Cost per run | Monthly cost (weekly runs) |
|----------------|-------------|---------------------------|
| 10 | $0.25 | ~$1.00 |
| 30 | $0.25 | ~$1.00 |
| 50 | $0.45 | ~$1.80 |
| 100 | $0.95 | ~$3.80 |

You pay for the ranked cross-source insight, not per API call. The compute cost is under one cent per run.

***

### How to use

#### Option 1: Apify Console

1. Open the Actor in [Apify Console](https://console.apify.com).
2. Paste your topic list into the **topics** field.
3. Click **Start**.
4. Read the results in the **Output** tab.

#### Option 2: API

**cURL:**

```bash
curl -X POST "https://api.apify.com/v2/acts/heartsome_stalactite~dev-trend-radar/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"topics":["vector-database","web-scraping","htmx"]}'
```

**JavaScript:**

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

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
const run = await client.actor('heartsome_stalactite/dev-trend-radar').call({
    topics: ['vector-database', 'web-scraping', 'htmx'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**Python:**

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_API_TOKEN')
run = client.actor('heartsome_stalactite/dev-trend-radar').call(run_input={
    'topics': ['vector-database', 'web-scraping', 'htmx'],
})
dataset = client.dataset(run.default_dataset_id).list_items()
for item in dataset.items:
    print(item['topic'], item['compositeScore'])
```

#### Option 3: Schedule weekly runs

Set a weekly schedule in Apify Console with the same input. The Actor saves snapshots by week, so your second run will show week-over-week deltas automatically.

***

### Limitations

- **PyPI is not supported.** Python's package registry does not offer a keyword search API, so only npm is used for package data.
- **GitHub unauthenticated limit is 10 searches per minute.** For more than 30 topics, set a `GITHUB_TOKEN` environment variable. A free token takes 10 seconds to create.
- **Stack Exchange allows 300 requests per day per IP.** This is enough for most use cases but shared infrastructure may hit the limit under heavy concurrent usage.
- **First run has no deltas.** The `weekOverWeekDelta` field is null on the first run because there is no prior snapshot. Run it again the next week to see change.
- **A topic absent from one source is valid signal, not an error.** If a topic has 0 npm packages, that means it has not been packaged yet. The Actor reports this as data.

***

### Troubleshooting

**My GitHub results are all zeros**

You likely hit the rate limit without a token. Create a free [GitHub personal access token](https://github.com/settings/tokens) and add it as the `GITHUB_TOKEN` environment variable in your Actor settings, then rerun.

**A Stack Overflow tag is showing as absent**

This is expected. It means the topic has no questions on that site yet. The Actor returns `tagCount: 0` and `tagAbsent: true`. This is useful signal, not a bug.

**My week-over-week deltas are null**

This happens on the first run. The Actor needs one prior weekly snapshot to compare against. Run it again the following week and you will see the change.

***

### Changelog

See [CHANGELOG.md](./CHANGELOG.md) for version history.

# Actor input Schema

## `topics` (type: `array`):

1–100 tech topics to rank. Lowercase kebab/snake style, e.g. "rust-web-frameworks", "vector-database". Invalid entries are skipped (not aborted) and listed in meta.invalidTopics.

## `schedule` (type: `string`):

Snapshot bucketing hint. Actual scheduling is handled by the Apify scheduler.

## `growthWindowWeeks` (type: `integer`):

Weeks back to read the prior snapshot for week-over-week delta. 1–52. First run has null deltas (no baseline).

## `maxTopics` (type: `integer`):

Cap applied after case-insensitive dedup. Topics beyond this cap are dropped and listed in meta.skippedTopics.

## `stackExchangeSite` (type: `string`):

Stack Exchange site for tag counts. Use the default (stackoverflow) unless you need a different community.

## Actor input object example

```json
{
  "topics": [
    "rust-web-frameworks",
    "vector-database"
  ],
  "schedule": "weekly",
  "growthWindowWeeks": 4,
  "maxTopics": 100,
  "stackExchangeSite": "stackoverflow"
}
```

# Actor output Schema

## `dataset` (type: `string`):

One row per topic with GitHub, Stack Overflow, and npm signals plus a composite trend score.

## `output` (type: `string`):

The full radar object with all rows sorted by score and run metadata.

# 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 = {
    "topics": [
        "rust-web-frameworks",
        "vector-database",
        "edge-compute",
        "webassembly",
        "llm-gateway",
        "open-telemetry",
        "golang-cli",
        "postgres-extensions"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("heartsome_stalactite/dev-trend-radar").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 = { "topics": [
        "rust-web-frameworks",
        "vector-database",
        "edge-compute",
        "webassembly",
        "llm-gateway",
        "open-telemetry",
        "golang-cli",
        "postgres-extensions",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("heartsome_stalactite/dev-trend-radar").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "topics": [
    "rust-web-frameworks",
    "vector-database",
    "edge-compute",
    "webassembly",
    "llm-gateway",
    "open-telemetry",
    "golang-cli",
    "postgres-extensions"
  ]
}' |
apify call heartsome_stalactite/dev-trend-radar --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=heartsome_stalactite/dev-trend-radar",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/3Rzn8Iv5LUaAMreJT/builds/ebDA2teQIke4GlM0E/openapi.json
