├── .gitignore ├── package.json ├── .github └── workflows │ └── build-and-release.yml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # These can get generated when running buildAndRelease.js locally, but we never 2 | # want to commit them: 3 | .idea/ 4 | node_modules/ 5 | package-lock.json 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "download-counts", 3 | "version": "2.0.0", 4 | "description": "Monthly download counts for every npm package, as a big static object.", 5 | "homepage": "https://github.com/nice-registry/download-counts#readme", 6 | "bugs": { 7 | "url": "https://github.com/nice-registry/download-counts/issues" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/nice-registry/download-counts.git" 12 | }, 13 | "license": "MIT", 14 | "type": "module", 15 | "main": "counts.json", 16 | "files": [ 17 | "counts.json" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /.github/workflows/build-and-release.yml: -------------------------------------------------------------------------------- 1 | run-name: Advance build periodically 2 | permissions: 3 | id-token: write 4 | contents: write 5 | on: 6 | schedule: 7 | # Run once per hour, at an arbitrary non-round-number minute to try to 8 | # dodge the high load on GitHub Actions that happens at the beginning of 9 | # each hour and leads to jobs being delayed. 10 | - cron: "41 * * * *" 11 | concurrency: 12 | group: ${{ github.workflow }} 13 | jobs: 14 | incrementally-build-release: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v5 18 | - uses: actions/setup-node@v6 19 | with: 20 | node-version: "lts/*" 21 | 22 | # At the time of writing, we need to update npm to 11.5.1 or later to 23 | # get support for Trusted Publishing via GitHub Actions. In future, once 24 | # the image and/or setup-node action give us that out of the box, we can 25 | # delete this step (and maybe also stop using setup-node if ubuntu-latest 26 | # contains a recent enough npm version). 27 | - name: Update npm 28 | run: npm install -g npm@latest 29 | 30 | # (So we can diagnose any breakages caused by new Node or npm releases) 31 | - name: Print Node & npm versions 32 | run: | 33 | node --version 34 | npm --version 35 | 36 | - run: | 37 | node buildAndRelease.js 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # download-counts 2 | 3 | The https://npmjs.org/package/download-counts package, updated with a new version once per month, just exports a single giant static object whose keys are package names and whose values are monthly download counts. 4 | 5 | To check monthly download counts of individual packages: 6 | 7 | ``` 8 | > const downloadCounts = require('download-counts') 9 | undefined 10 | > downloadCounts.lodash 11 | 310086369 12 | > downloadCounts.react 13 | 169846525 14 | > downloadCounts.typescript 15 | 365742011 16 | > downloadCounts.nonexistentpackage 17 | undefined 18 | ``` 19 | 20 | To get the top *n* packages, just sort the package & count pairs by count, then take the top *n*. e.g.: 21 | 22 | ```javascript 23 | /** Print the top n packages by download count */ 24 | function printTopPackages(n) { 25 | for (const [name, count] of Object.entries(downloadCounts).sort( 26 | ([_, cnt1], [__, cnt2]) => cnt2 - cnt1 27 | ).slice(0, n)) { 28 | console.log(name, count); 29 | } 30 | } 31 | ``` 32 | 33 | ``` 34 | > printTopPackages(10) 35 | semver 1819920988 36 | ansi-styles 1714990182 37 | debug 1587998302 38 | chalk 1430249785 39 | supports-color 1427520560 40 | minimatch 1238345778 41 | ms 1212057951 42 | tslib 1140382329 43 | strip-ansi 1114443532 44 | ansi-regex 1028842864 45 | ``` 46 | 47 | 48 | ### History/Maintenance/Contributing/Debugging 49 | 50 | A version of download-counts was written by [@zeke](https://github.com/zeke) in 2017, then abandoned. It was replaced by a new version by [@ExplodingCabbage](https://github.com/ExplodingCabbage) in 2025. 51 | 52 | The build process for generating a new release runs once per month, and takes most of the month to run due to the npm API's very aggressive rate limiting. It runs in GitHub Actions (for free), where a scheduled job repeatedly calls a single script that, whenever it's called, advances the build a bit by fetching more download counts from the npm API and recording them in source control on a branch specific to that release. 53 | 54 | Please report bugs (including the npm package not getting updated with new versions) as [GitHub issues](https://github.com/nice-registry/download-counts/issues). 55 | 56 | Hopefully all this will keep working for years and publishing new versions without needing any maintenance. If not, [@ExplodingCabbage](https://github.com/ExplodingCabbage) has maintainer access on GitHub and will try to fix it. He can be contacted at markrobertamery@gmail.com. 57 | 58 | Failures in the build process will result in a failed GitHub Action, visible at https://github.com/nice-registry/download-counts/actions. The logged output there may be sufficient to debug; if not, you can checkout the latest build branch locally and run `node buildAndRelease.js` yourself. Credentials are only needed for pushing commits to GitHub and publishing to npm; the rest of what the script does does not require any creds. Change the remote `origin` to a fork you have push access to before testing in order to allow Git pushes to succeed. 59 | --------------------------------------------------------------------------------