Undercurrent

How it works

Every number on this site comes from public data and plain statistics. Here is exactly how.

Where the data comes from

Downloads come from the npm, PyPI, crates.io, Packagist and RubyGems registries. npm history goes back to 2015. PyPI only publishes the last six months, so Python history grows from the day collection started. GitHub provides stars, commits, contributors, releases and how fast maintainers answer new issues. Star history is rebuilt by sampling the dates of a repository's stargazers.

Community attention comes from Hacker News mentions, Stack Overflow questions and dev.to articles. Hiring demand comes from the monthly “Who is hiring” threads on Hacker News, counted as a share of all posts so busy months don't look like growth. Security advisories come from OSV.

Finding switches

The miner reads the history of public repositories found through GitHub search. For every commit that touched a dependency file (package.json, requirements files, pyproject.toml, Cargo.toml, go.mod, composer.json, Gemfile) it rebuilds the full dependency list. It also watches telltale files like lockfiles and CI configs, which is how it sees Yarn give way to pnpm or Travis CI give way to GitHub Actions.

A switch is counted when a tool leaves a repository and a direct rival from the same category arrives in the same commit or within 45 days. Both changes must last at least 90 days, so brief experiments don't count. A repository's own packages are ignored.

Cleaning the signals

Download counts include bots and CI bursts. Weekly spikes far above the local median are replaced with that median before anything else is calculated. npm downloads are measured as a share of all npm downloads, so the registry's own growth doesn't make every package look like it is rising. Incomplete months are left out.

Momentum

For each signal, growth blends the past year (60%) with the past three months (40%). Each tool's growth is ranked against every other tool with that signal, and the ranks are averaged with weights: downloads 34%, job posts 16%, stars 14%, Stack Overflow 10%, Hacker News 10%, commits 10%, dev.to 6%. Tools with few signals are pulled toward the middle. Raw numbers sit next to every score, because a mature tool can be healthy and still grow slowly.

Lifecycle stages

Stages come from the main usage signal. Legacy: archived, deprecated, or below half its peak and still falling. Declining: down more than 12% in a year, or losing more than 5 points of category share. Emerging: under 30 months of history and growing, or under 5% share and growing over 50% a year. Rising: growing over 25% a year or gaining share. Mainstream: at least 15% of its category or in the top fifth by usage. Plateau: everything else.

A breakout is a small tool, at most five years old, that at least doubled in a year or grew 40% in three months, with most of its signals pointing up.

Forecasts, graded in public

Forecasts use damped trend smoothing on the log of monthly usage, fitted to the last four years. The shaded range is where the value should land 80% of the time. To check that, the model is re-run as if it were 6, 12 and 18 months ago, and its predictions are compared with what actually happened.

Known limits

Public repositories found through search lean toward popular open-source projects, not private company code. Mention counts can catch unrelated uses of common words, so ambiguous names are searched with qualified phrases like “golang” or “next.js”. Package managers and CI tools are detected from files, which a few projects keep for compatibility after switching. See data status for how fresh each source is.