{"id":15290291,"url":"https://github.com/npm/download-counts","last_synced_at":"2025-10-07T03:32:47.451Z","repository":{"id":14198513,"uuid":"16905103","full_name":"npm/download-counts","owner":"npm","description":"Background jobs and a minimal service for collecting and delivering download counts","archived":true,"fork":false,"pushed_at":"2020-03-24T19:01:08.000Z","size":2055,"stargazers_count":329,"open_issues_count":12,"forks_count":27,"subscribers_count":35,"default_branch":"master","last_synced_at":"2024-10-01T16:06:49.282Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/npm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-02-17T07:27:29.000Z","updated_at":"2024-06-18T01:42:21.000Z","dependencies_parsed_at":"2022-09-09T02:11:23.746Z","dependency_job_id":null,"html_url":"https://github.com/npm/download-counts","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/npm%2Fdownload-counts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/npm%2Fdownload-counts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/npm%2Fdownload-counts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/npm%2Fdownload-counts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/npm","download_url":"https://codeload.github.com/npm/download-counts/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235586082,"owners_count":19014028,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-30T16:06:49.220Z","updated_at":"2025-10-07T03:32:41.835Z","avatar_url":"https://github.com/npm.png","language":"JavaScript","funding_links":[],"categories":["Documentation"],"sub_categories":["Standalone version of a package"],"readme":"# npm stats microservice\n\n__Note!__ This code base isn't what npm uses to serve download counts anymore, and its documentation is likely to drift out of correctness as time passes. See [the registry API documentation](https://github.com/npm/registry/blob/master/docs/download-counts.md) for up-to-date usage info.\n\nGives you download counts. Eventually, maybe other stuff.\n\nOur blog has an explanation of [how npm download counts work](http://blog.npmjs.org/post/92574016600/numeric-precision-matters-how-npm-download-counts), including \"what counts as a download?\"\n\n## Data source\n\nnpm's raw log data is continuously written to a series of buckets on AWS S3. Once per day, soon \nafter UTC midnight, a map-reduce cluster is spun up that crunches the previous day's logs and\npushes them into the database. Because this is UTC this creates some slightly unintuitive results,\ne.g. if you are on the west coast on the 19th of September, the data for the 19th of September will\nbecome available at 5pm (because UTC already moved to the 20th) during the winter, but not until 6pm\nduring the summer, because the US observes daylight savings but UTC is fixed.\n\n## Point values\n\nGets the total downloads for a given period, for all packages or a specific package.\n\n\u003ccode\u003eGET https://api.npmjs.org/downloads/point/{period}[/{package}]\u003c/code\u003e\n\n### Examples\n\n\u003cdl\u003e\n\t\u003cdt\u003eAll packages, last day:\u003c/dt\u003e\n\t\u003cdd\u003e\u003ca href=\"https://api.npmjs.org/downloads/point/last-day\"\u003e/downloads/point/last-day\u003c/a\u003e\u003c/dd\u003e\n\t\u003cdt\u003eAll packages, specific date:\u003c/dt\u003e\n\t\u003cdd\u003e\u003ca href=\"https://api.npmjs.org/downloads/point/2014-02-01\"\u003e/downloads/point/2014-02-01\u003c/a\u003e\u003c/dd\u003e\n\t\u003cdt\u003ePackage \"express\", last week:\u003c/dt\u003e\n\t\u003cdd\u003e\u003ca href=\"https://api.npmjs.org/downloads/point/last-week/express\"\u003e/downloads/point/last-week/express\u003c/a\u003e\u003c/dd\u003e\n\t\u003cdt\u003ePackage \"express\", given 7-day period:\u003c/dt\u003e\n\t\u003cdd\u003e\u003ca href=\"https://api.npmjs.org/downloads/point/2014-02-01:2014-02-08/express\"\u003e/downloads/point/2014-02-01:2014-02-08/express\u003c/a\u003e\u003c/dd\u003e\n\t\u003cdt\u003ePackage \"jquery\", last 30 days:\u003c/dt\u003e\n\t\u003cdd\u003e\u003ca href=\"https://api.npmjs.org/downloads/point/last-month/jquery\"\u003e/downloads/point/last-month/jquery\u003c/a\u003e\u003c/dd\u003e\n\t\u003cdt\u003ePackage \"jquery\", specific month:\u003c/dt\u003e\n\t\u003cdd\u003e\u003ca href=\"https://api.npmjs.org/downloads/point/2014-01-01:2014-01-31/jquery\"\u003e/downloads/point/2014-01-01:2014-01-31/jquery\u003c/a\u003e\u003c/dd\u003e\n\u003c/dl\u003e\n\n### Parameters\n\nAcceptable values are:\n\n\n\u003cdl\u003e\n\t\u003c!--\n\t\u003cdt\u003eall-time\u003c/dt\u003e\n\t\u003cdd\u003eGets total downloads.\u003c/dd\u003e\n\t--\u003e\n\t\u003cdt\u003elast-day\u003c/dt\u003e\n\t\u003cdd\u003eGets downloads for the last available day. In practice, this will usually be \"yesterday\" (in GMT) but if stats for that day have not yet landed, it will be the day before.\u003c/dd\u003e\n\t\u003cdt\u003elast-week\u003c/dt\u003e\n\t\u003cdd\u003eGets downloads for the last 7 available days.\u003c/dd\u003e\n  \t\u003cdt\u003elast-month\u003c/dt\u003e\n\t\u003cdd\u003eGets downloads for the last 30 available days.\u003c/dd\u003e\n\u003c/dl\u003e\n\n### Output\n\nThe following incredibly simple JSON is the output:\n\n```javascript\n{\n  downloads: 31623,\n  start: \"2014-01-01\",\n  end: \"2014-01-31\",\n  package: \"jquery\"\n}\n```\n\nIf you have not specified a package, that key will not be present. The start and end dates are inclusive.\n\n## Ranges\n\nGets the downloads per day for a given period, for all packages or a specific package.\n\n\u003ccode\u003eGET https://api.npmjs.org/downloads/range/{period}[/{package}]\u003c/code\u003e\n\n### Examples\n\n\u003cdl\u003e\n\t\u003cdt\u003eDownloads per day, last 7 days\u003c/dt\u003e\n\t\u003cdd\u003e\u003ca href=\"https://api.npmjs.org/downloads/range/last-week\"\u003e/downloads/range/last-week\u003c/a\u003e\u003c/dd\u003e\n\t\u003cdt\u003eDownloads per day, specific 7 days\u003c/dt\u003e\n\t\u003cdd\u003e\u003ca href=\"https://api.npmjs.org/downloads/range/2014-02-07:2014-02-14\"\u003e/downloads/range/2014-02-07:2014-02-14\u003c/a\u003e\u003c/dd\u003e\n\t\u003cdt\u003eDownloads per day, last 30 days\u003c/dt\u003e\n\t\u003cdd\u003e\u003ca href=\"https://api.npmjs.org/downloads/range/last-month/jquery\"\u003e/downloads/range/last-month/jquery\u003c/a\u003e\u003c/dd\u003e\n\t\u003cdt\u003eDownloads per day, specific 30 day period\u003c/dt\u003e\n\t\u003cdd\u003e\u003ca href=\"https://api.npmjs.org/downloads/range/2014-01-03:2014-02-03/jquery\"\u003e/downloads/range/2014-01-03:2014-02-03/jquery\u003c/a\u003e\u003c/dd\u003e\n\u003c/dl\u003e\n\n### Parameters\n\nSame as for /downloads/point.\n\n### Output\n\nResponses are very similar to the point API, except that downloads is now an array of days with downloads on each day:\n\n```javascript\n{\n\tdownloads: [\n\t\t{\n\t\t\tday: \"2014-02-27\",\n\t\t\tdownloads: 1904088\n\t\t},\n\t\t..\n\t\t{\n\t\t\tday: \"2014-03-04\",\n\t\t\tdownloads: 7904294\n\t\t}\n\t],\n\tstart: \"2014-02-25\",\n\tend: \"2014-03-04\",\n\tpackage: \"somepackage\"\n}\n```\n\nAs before, the package key will not be present if you have not specified a package.\n\n## Bulk Queries\n\nTo perform a bulk query, you can hit the range or point endpoints with a comma\nseparated list of packages rather than a single package, e.g.,\n\n`/downloads/point/last-day/npm,express`\n\n## Development\n\nThe code requires node and a mysql database to talk to. We have a conveniently\npre-configured VM available for download. First, install VirtualBox:\n\nhttps://www.virtualbox.org/wiki/Downloads\n\nAnd then install Vagrant:\n\nhttps://www.vagrantup.com/downloads.html\n\nNow just cd into the root of this repo and run\n\n\u003ccode\u003evagrant up\u003c/code\u003e\n\nWhen you see \"Done!\" you are ready to rock.\n\n### Running the web service\n\nInstall dependencies:\n\n\u003ccode\u003enpm install\u003c/code\u003e\n\nYou will need a config file:\n\n\u003ccode\u003ecp test/config.dev.js config.js\u003c/code\u003e\n\nFor development, you shouldn't need to change anything in here\nunless your VM didn't come up at the usual IP (192.168.33.10)\n\nRun the server on port 3000:\n\n\u003ccode\u003enode index.js 3000\u003c/code\u003e\n\nTest that it's working:\n\n\u003ccode\u003ecurl \"http://localhost:3000/downloads/point/2014-03-01\"\u003c/code\u003e\n\nYou can ssh into the VM to play with MySQL or whatever:\n\n\u003ccode\u003evagrant ssh\u003c/code\u003e\n\n### Importing data from S3 (npm, Inc. only)\n\nNew data is generated daily and stored in S3. You can get it with the \nbackfill script like so:\n\n\u003ccode\u003enode scripts/backfill.js YYYY-MM-DD N\u003c/code\u003e\n\nYYYY-MM-DD is the date you want new data to start. If omitted,\nit will start importing from the first available data, which is\na bad idea except when creating a new production host\n\nN is the number of days to import after that date. If omitted,\nit will import all available days. So to get everything after\nApril 1, for instance, run\n\n\u003ccode\u003enode scripts/backfill.js 2014-04-01\u003c/code\u003e\n\nFor the AWS JS SDK to work, you must have a `~/.aws/credentials` file \ncontaining\n\n```\naws_access_key_id = XXXXX\naws_secret_access_key = YYYYY\n```\n\nWhere X and Y are your AWS access credentials. The production server has\nits own credentials specifically for this purpose.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnpm%2Fdownload-counts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnpm%2Fdownload-counts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnpm%2Fdownload-counts/lists"}