npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

google-trends-now

v1.1.1

Published

Unofficial CLI and Node.js client for Google Trends Trending Now, with RSS fallback.

Downloads

97

Readme

google-trends-now

English | 简体中文

CI npm version node license: MIT

Unofficial CLI and Node.js client for Google Trends Trending Now, with an RSS fallback. Zero runtime dependencies.

Not an official Google client. It reads the current Trending Now web data path and falls back to Google Trends RSS when that path fails. RSS is a limited best-effort fallback, not the full Trending Now pool. Google's official Trends API alpha targets scaled search-interest data and does not yet cover this hot-word discovery use case.

google-trends-now: piping trending topics through jq

Live snapshot — npx google-trends-now trending --geo US --hours 48 --sort volume --limit 5 --format json | jq '...'. Actual output changes with the news cycle.

Install

Requires Node.js >= 22 (built-in fetch, AbortSignal.timeout, Array.prototype.toSorted).

npm install google-trends-now

CLI

google-trends-now trending --geo US --hours 48 --format json
google-trends-now trending --category technology --status active --format ndjson
google-trends-now rss --geo US --format json
google-trends-now categories
google-trends-now healthcheck

| Option | Values | Default | |---|---|---| | --geo | country/region code | US | | --hours | 4 24 48 168 | 48 | | --category | alias or numeric id | all | | --status | all active ended | all | | --sort | relevance volume recency title | relevance | | --limit | integer or all (no truncation) | 100 | | --format | json ndjson csv markdown | json | | --hl | locale | en | | --fallback | rss none | rss | | --timeout-ms | integer | 30000 | | --retries | integer; retry transient 429/5xx/network failures | 0 | | --include-raw | flag; attach the pre-normalization batchexecute payload as raw (json format only) | off | | --with-news | integer 1-10; resolve news articles for the first n items into a news field (trending command, json format only) | off | | -h, --help · -v, --version | | |

Category filtering is always applied locally against each row's categories[]; the request-side category is only an upstream hint. Unknown categories and misspelled flags (e.g. --categroy) fail fast rather than being silently ignored.

--retries opts into a restrained retry that only covers transient 429/5xx/network failures (a 429 honors Retry-After, capped at 30s); it is a defense against a single blip, not a way to grind past rate limiting. --include-raw and --with-news require --format json and fail fast otherwise.

  • Exit codes: 0 success · 1 healthcheck not-ok · 2 usage/validation/runtime error.
  • healthcheck probes the primary endpoint only (forces --fallback none, so RSS can't mask an outage) and always prints JSON { ok, elapsed_ms, fetch_status, source, error, item_count }. ok is true only on fetch_status: "success" with at least one item; the process exits 0/1 accordingly.
  • categories prints the alias table and honors --format; its json output is a bare [{ alias, id, name }] array, not the result envelope.

SDK

import { fetchTrendingNews, fetchTrendingNow, fetchTrendingRss, formatMarkdown } from "google-trends-now";

const output = await fetchTrendingNow({
  geo: "US",
  hours: 48,
  category: "technology",
  status: "active",
  limit: 25
});

console.log(formatMarkdown(output));

const news = await fetchTrendingNews(output.items[0].news_refs.slice(0, 5));
console.log(news[0]?.title); // resolved article headline

const rss = await fetchTrendingRss({ geo: "US", limit: 10 });
console.log(rss.fetch_status); // "rss_limited"

Also exported: categories, categoryRows, normalizeTrendingRow, formatJson, formatNdjson, formatCsv, parseTrendingRssXml, and the low-level batchexecute helpers. Full field types ship in the bundled index.d.ts.

Output schema

fetchTrendingNow(options) resolves to an envelope:

{
  observed_at: "2026-07-06T00:00:00.000Z",
  geo: "US", hours: 48, category: "all", status: "all", sort: "relevance",
  source: "google_trending_now",   // or "rss_limited"
  fetch_status: "success",         // or "rss_limited" | "manual_review_required"
  source_url: "https://trends.google.com/trending?geo=US&hl=en&hours=48",
  error: null,
  items: [ /* ... */ ]
}

category_filter_status / status_filter_status are optional keys added only on RSS output when a category/status filter was requested (see RSS fallback); they are absent on the normal path.

Each item:

{
  position: 1, raw_position: 1,
  query: "example trend", normalized_query: "example trend",
  search_volume: 50000, search_volume_label: "50000+",
  increase_percentage: 200,
  started_at: "2026-07-06T00:00:00.000Z", ended_at: null,
  start_timestamp: 1783296000, end_timestamp: null,
  active: true,
  trend_breakdown: ["example trend"],
  categories: [{ id: 18, name: "Technology" }],
  explore_url: "https://trends.google.com/trends/explore?...",
  source: "google_trending_now"
}

Formats

| Format | Output | |---|---| | json | full envelope | | ndjson | one normalized item per line | | csv | flat rows; categories and breakdown joined by ; (formula-injection safe) | | markdown | compact report table |

RSS fallback

When the Trending Now request fails and --fallback rss is on, the client fetches https://trends.google.com/trending/rss?geo=<geo> and marks the output source: "rss_limited", fetch_status: "rss_limited".

RSS lacks the category, active-status, and full trend-pool fields of Trending Now, so it is best-effort only. If a category/status filter was requested, the rows are kept and flagged with category_filter_status/status_filter_status: "unavailable_in_rss".

Disclaimer & license

Google Trends numbers are approximate search-interest signals: volume labels are not sales, demand, or market size, and trending rank is not opportunity rank. The internal endpoint is undocumented and may change, throttle, or require manual review; this package uses no browser automation, login, proxy rotation, or CAPTCHA bypass.

MIT licensed (LICENSE). "Google" and "Google Trends" are trademarks of Google; this project is unofficial and not endorsed by Google.

Development

npm test                                  # node --test, no network
npm run lint                              # eslint (flat config)
node bin/google-trends-now.mjs categories # offline smoke check
npx . trending --geo US --limit 5         # run from a checkout
npm pack --dry-run                        # inspect the publishable tarball

See CONTRIBUTING.md, SECURITY.md, and CHANGELOG.md.

Releasing

Releases are cut manually (low release cadence does not justify automation):

  1. Bump version in package.json and date the ## Unreleased section in CHANGELOG.md; commit and tag vX.Y.Z.
  2. npm publishprepublishOnly runs the tests and lint automatically.

简体中文

非官方 Google Trends Trending Now 命令行工具和 Node.js SDK,带 RSS 兜底。零运行时依赖。

不是 Google 官方客户端。它优先读取当前 Trending Now 网页数据路径,失败时降级读取 Google Trends RSS。RSS 只是有限的 best-effort 兜底,不是完整 Trending Now 池。Google 官方 Trends API alpha 面向可缩放的搜索兴趣数据,暂不覆盖本项目的热词发现用途。

安装

需要 Node.js >= 22(内置 fetchAbortSignal.timeoutArray.prototype.toSorted)。

npm install google-trends-now

命令行

google-trends-now trending --geo US --hours 48 --format json
google-trends-now trending --category technology --status active --format ndjson
google-trends-now rss --geo US --format json
google-trends-now categories
google-trends-now healthcheck

| 参数 | 取值 | 默认 | |---|---|---| | --geo | 国家/地区代码 | US | | --hours | 4 24 48 168 | 48 | | --category | 别名或数字 id | all | | --status | all active ended | all | | --sort | relevance volume recency title | relevance | | --limit | 整数或 all(不截断) | 100 | | --format | json ndjson csv markdown | json | | --hl | 语言 locale | en | | --fallback | rss none | rss | | --timeout-ms | 整数 | 30000 | | --retries | 整数;对瞬时的 429/5xx/网络失败重试 | 0 | | --include-raw | 布尔开关;在 json 输出的信封上附加 normalize 前的原始 batchexecute payload(raw 字段,仅 json 格式) | 关 | | --with-news | 整数 1-10;为前 n 条结果解析新闻文章并写入 news 字段(仅 trending 命令 + json 格式) | 关 | | -h, --help · -v, --version | | |

分类过滤一定基于每条结果返回的 categories[] 在本地执行;请求参数里的分类只是上游提示。未知分类和拼错的参数(例如 --categroy)会直接报错,而不是被静默忽略。

--retries 开启的是克制的重试,只覆盖瞬时的 429/5xx/网络失败(429 会尊重 Retry-After,封顶 30 秒),用于抵抗单次抖动,而不是绕过限流。--include-raw--with-news 都要求 --format json,否则直接报错。

  • 退出码: 0 成功 · 1 healthcheck not-ok · 2 用法/校验/运行时错误。
  • healthcheck 只探测主接口(内部强制 --fallback none,RSS 兜底不会掩盖故障),并且始终输出 JSON { ok, elapsed_ms, fetch_status, source, error, item_count }。只有 fetch_status: "success" 且至少一条结果时 ok 才为 true,进程据此退出 0/1
  • categories 打印分类别名表并支持 --format;它的 json 输出是裸数组 [{ alias, id, name }],不是结果包。

SDK

import { fetchTrendingNow, fetchTrendingRss, formatMarkdown } from "google-trends-now";

const output = await fetchTrendingNow({
  geo: "US",
  hours: 48,
  category: "technology",
  status: "active",
  limit: 25
});

console.log(formatMarkdown(output));

const rss = await fetchTrendingRss({ geo: "US", limit: 10 });
console.log(rss.fetch_status); // "rss_limited"

另外导出:categoriescategoryRowsnormalizeTrendingRowformatJsonformatNdjsonformatCsvparseTrendingRssXml,以及底层 batchexecute 辅助函数。完整字段类型见随包发布的 index.d.ts

输出结构

fetchTrendingNow(options) 返回一个结果包:

{
  observed_at: "2026-07-06T00:00:00.000Z",
  geo: "US", hours: 48, category: "all", status: "all", sort: "relevance",
  source: "google_trending_now",   // 或 "rss_limited"
  fetch_status: "success",         // 或 "rss_limited" | "manual_review_required"
  source_url: "https://trends.google.com/trending?geo=US&hl=en&hours=48",
  error: null,
  items: [ /* ... */ ]
}

category_filter_status / status_filter_status 是可选字段,在使用 RSS 且请求了 category/status 过滤时出现(见 RSS 兜底),正常路径上不会有。

单条结果:

{
  position: 1, raw_position: 1,
  query: "example trend", normalized_query: "example trend",
  search_volume: 50000, search_volume_label: "50000+",
  increase_percentage: 200,
  started_at: "2026-07-06T00:00:00.000Z", ended_at: null,
  start_timestamp: 1783296000, end_timestamp: null,
  active: true,
  trend_breakdown: ["example trend"],
  categories: [{ id: 18, name: "Technology" }],
  explore_url: "https://trends.google.com/trends/explore?...",
  source: "google_trending_now"
}

输出格式

| 格式 | 输出 | |---|---| | json | 完整结果包 | | ndjson | 每行一条标准化结果 | | csv | 扁平表格;分类名和 breakdown 用 ; 连接(已防 CSV 公式注入) | | markdown | 适合报告的紧凑表格 |

RSS 兜底

当 Trending Now 请求失败且启用 --fallback rss 时,客户端会请求 https://trends.google.com/trending/rss?geo=<geo>,并把输出标记为 source: "rss_limited"fetch_status: "rss_limited"

RSS 不含 Trending Now 的分类、活跃状态和完整趋势池字段,只能作为 best-effort 兜底。如果请求了 category/status 过滤,结果会保留并标记 category_filter_status/status_filter_status: "unavailable_in_rss"

免责声明与协议

Google Trends 数值是近似搜索兴趣信号:搜索量标签不等于销量、需求或市场规模,Trending rank 也不等于机会排序。内部接口没有官方文档,可能变化、限流或需要人工复核;本项目不使用浏览器自动化、登录、代理轮换或验证码绕过。

MIT 协议(LICENSE)。"Google"、"Google Trends" 是 Google 的商标;本项目为非官方项目,未获 Google 背书。

开发

npm test                                  # node --test,无网络
node bin/google-trends-now.mjs categories # 离线冒烟检查
npx . trending --geo US --limit 5         # 在源码仓库中直接运行
npm pack --dry-run                        # 查看可发布 tarball

参见 CONTRIBUTING.mdSECURITY.mdCHANGELOG.md