A Node.js Trends API client is a Bearer-authenticated POST to https://api.trendsapi.ai/api, then a second JSON.parse on the body string. On 2026-08-09, Google Search interest for Node.js sat at 42.0 on 2026-08-08 with 30D growth of -35.38%, 3M of -49.4%, 6M of 16.67%, and 12M of 90.91%. The same pull on the npm source showed react at score 100.0 with 162,776,333 weekly downloads on 2026-08-08 and 12M volume growth of 289.26%. That pairing is the point of the integration: search interest and package volume share one JSON contract.

Minimal fetch client

Node 18+ ships fetch. Set TRENDSAPI_API_KEY and keep the double parse in one helper. Free tier allows 100 successful requests per month. Only HTTP 200 responses count against quota. Starter is 5,000, Pro is 25,000, Business is 100,000.

const API_URL = "https://api.trendsapi.ai/api";
const API_KEY = process.env.TRENDSAPI_API_KEY;

async function trendsApi(payload) {
  const res = await fetch(API_URL, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(payload),
  });
  if (!res.ok) {
    throw new Error(`HTTP ${res.status}`);
  }
  const envelope = await res.json();
  // body is a JSON string; parse it a second time
  return JSON.parse(envelope.body);
}

const growth = await trendsApi({
  mode: "get_growth",
  source: "google search",
  keyword: "Node.js",
  percent_growth: ["30D", "3M", "6M", "12M"],
});
console.log(growth.results[0].growth);

The first mistake most clients make is reading envelope.body.results. That fails because body is still a string after res.json().

Google Search growth for Node ecosystem terms

Pulled on 2026-08-09 with source set to google search. Recent points land on 2026-08-08.

Keyword Period Recent value Baseline date Baseline value Growth
Node.js 30D 42.0 2026-07-11 65.0 -35.38%
Node.js 3M 42.0 2026-05-09 83.0 -49.4%
Node.js 6M 42.0 2026-02-07 36.0 16.67%
Node.js 12M 42.0 2025-08-09 22.0 90.91%
TypeScript 7D 32.0 2026-08-01 49.0 -34.69%
TypeScript 30D 32.0 2026-07-11 79.0 -59.49%
TypeScript 3M 32.0 2026-05-09 89.0 -64.04%
TypeScript 12M 32.0 2025-08-09 49.0 -34.69%
react 7D 46.0 2026-08-01 51.0 -9.8%
react 30D 46.0 2026-07-11 71.0 -35.21%
react 3M 46.0 2026-05-09 96.0 -52.08%
react 12M 46.0 2025-08-09 60.0 -23.33%
Next.js 7D 13.0 2026-08-01 21.0 -38.1%
Next.js 30D 13.0 2026-07-11 54.0 -75.93%
Next.js 3M 13.0 2026-05-09 61.0 -78.69%
Next.js 12M 13.0 2025-08-09 23.0 -43.48%

Node.js is up 90.91% over 12M while short windows are down. Next.js sits at 13.0 with a 30D drop of -75.93%. Keep both windows in the payload; they answer different questions.

For source docs and field notes, see Google Search trends. For a Python twin of this client pattern, see the Python Trends API guide.

npm volumes on the npm source

Keywords on source: "npm" must be exact package names as listed on the registry. Pulled on 2026-08-09 with custom dates ending on 2026-08-08 so the comparison skips a sparse tip week that returned score 0.0 and volume 0 on 2026-08-15 for preset windows.

Package Window Score Recent volume Baseline volume Score growth Volume growth
react ~30D 100.0 162,776,333 153,316,909 6.16% 6.17%
react ~3M 100.0 162,776,333 126,151,303 29.03% 29.03%
react ~6M 100.0 162,776,333 86,477,138 88.32% 88.23%
react ~12M 100.0 162,776,333 41,816,890 289.11% 289.26%
next ~30D 95.2 52,322,903 44,699,800 17.1% 17.05%
next ~3M 95.2 52,322,903 32,833,548 59.46% 59.36%
next ~6M 95.2 52,322,903 35,841,233 46.01% 45.99%
next ~12M 95.2 52,322,903 16,164,594 223.81% 223.69%
express ~1M to Jul 25 96.1 122,886,309 109,631,397 12.14% 12.09%
express ~3M to Jul 25 96.1 122,886,309 93,038,148 32.01% 32.08%
express ~6M to Jul 25 96.1 122,886,309 60,193,051 104.03% 104.15%
express ~12M to Jul 25 96.1 122,886,309 43,787,159 180.99% 180.64%

react hit the local max score of 100.0 on 2026-08-08. next trailed at 95.2 with faster 30D score growth (17.1% vs 6.16%). express still shows 180.99% score growth over ~12M ending 2026-07-25.

Custom date objects in percent_growth look like this:

const npmGrowth = await trendsApi({
  mode: "get_growth",
  source: "npm",
  keyword: "react",
  percent_growth: [
    { name: "30d_to_aug8", recent: "2026-08-08", baseline: "2026-07-11" },
    { name: "12m_to_aug8", recent: "2026-08-08", baseline: "2025-08-09" },
  ],
});

Field notes for package downloads live on the npm trends page. For a product-demand walkthrough that uses the same Node helper against Amazon and Google Shopping, see soccer cleats multi-source signals in Node.

get_time_series for charts and alerts

When a dashboard needs every weekly point, switch mode to get_time_series. The react series returned 261 points on 2026-08-09. Recent complete weeks included 2026-08-01 at score 99.7 with volume 162,348,333 and 2026-08-08 at score 100.0 with volume 162,776,333. The next stub week 2026-08-15 returned 0.0 / 0; treat that tip as incomplete until volume is non-zero.

const series = await trendsApi({
  mode: "get_time_series",
  source: "npm",
  keyword: "react",
});
const complete = series.filter((row) => row.volume > 0);
const last = complete[complete.length - 1];
console.log(last.date, last.value, last.volume);

Use get_top_trends only for live boards with no keyword. On 2026-08-09 the Google Trends board listed perez hilton at rank 1 and spokane fires at rank 2 as of 2026-08-09T10:01:34Z.

Error handling and quotas

Check HTTP status before parsing. Then check statusCode on the envelope. Growth rows can return per-period status: "error" with codes such as collapsed_range or date_out_of_range while other periods still succeed. Log the period and keep the successful rows.

Quota reminder: only successful 200 responses count. A failed auth call does not burn the free 100. Cache responses for cron jobs that poll the same keyword every hour.

When to use this over scrapers

A Node scraper against unofficial Google Trends endpoints breaks when cookies or consent walls change. Trends API keeps one endpoint, Bearer auth, and a 0-100 score across Google Search, npm, Amazon, TikTok, and the rest of the documented source list. For broader alternative framing, see the Google Trends API alternative page.