How To Get Millions Of Downloads On Your NPM Package
Download the npm-downloads-increaser package and run from the command line. Capable of handling 100+ downloads/second.
What does it do?
It’s like running npm install -g <my package>
over and over again, as fast as possible. This will increase the number of Weekly Downloads for your package on npmJS.
Turning this:
Into this:
The changes in download numbers will also propagate to other package managers, such as yarnpkg.
Why should I use this?
- It increases the popularity score of your NPM package, which increases its package score via the npms.io ranking algorithm
- Packages with a higher popularity score have increased visibility on npmJS
- Some users are more likely to download a package that already has a high number of weekly downloads
Why shouldn’t I use this?
- It wastes the resources of npmJS, an open source company.
- npmJS shows weekly downloads only. You would need to run this regularly to keep the weekly downloads high.
- Weekly downloads is not an accurate measure of the value of an NPM package.
- Faking the popularity of your own NPM package is kinda cringe.
How do I use this?
Install npm-downloads-increaser
globally:
npm i -g npm-downloads-increaser
Then start increasing your downloads:
npm-downloads-increaser
You will then be prompted to set some configurations:
Property | Description | Example |
packageName | NPM package to increase the downloads of | npm-downloads-increaser |
numDownloads | Number of times to download the package | 100000 |
maxConcurrentDownloads | Amount of downloads to run in parallel at once | 300 |
downloadTimeout | Max time (in ms) to wait for for a download to complete | 3000 |
You should experiment with different values for maxConcurrentDownloads
and downloadTimeout
to find the combination which maximises the download rate for your package. By default these values are set to 300 and 3000 respectively. These values resulted in an average download rate of 40dl/s when targeting a 20kB package from my computer.
In general, you will want a lower maxConcurrentDownloads
or higher downloadTimeout
if:
- Your package is large in size
- Your network is slow
How does it work?
First we must determine a valid package version. This can be done by querying the npms.io database, as the response will include the latest version number of the specified package. For this, we use queryNpms()
:
const queryNpms = async (): Promise<NpmjsResponse> => {
const npmsResponse: GaxiosResponse<NpmjsResponse> = await request<NpmjsResponse>({
baseUrl: "https://api.npms.io",
url: `/v2/package/${getConfig().packageName}`,
method: "GET",
}).catch((response: GaxiosError<NpmjsResponse>) => {
throw Error(`Failed to download ${response.config.url}\n${response.message}`);
});
return npmsResponse.data;
};
Now that we have a valid package version, we can construct the download URL for npmJS. The downloadPackage()
method behaves similarly to npm install <my package>
, and will increment the number of downloads for your package by +1.
downloadTimeout
specifies the maximum time to wait for the download to succeed. If the download times out, or fails for any other reason, then it is discarded.
const downloadPackage = async (version: string, stats: Stats): Promise<unknown> => {
return request<unknown>({
baseUrl: "https://registry.npmjs.com",
url: `/${getConfig().packageName}/-/${getConfig().packageName}-${version}.tgz`,
method: "GET",
timeout: getConfig().downloadTimeout,
responseType: "stream",
})
.then((_) => {
stats.successfulDownloads++;
})
.catch((_) => {
stats.failedDownloads++;
});
};
To increment the number of downloads on your package as fast as possible, we use the spamDownloads()
method. This generates maxConcurrentDownloads
http requests and executes them in parallel using Promise.all()
.
It will then check whether the number of successful downloads has exceeded your specified numDownloads
. If not, then it will run again recursively.
const spamDownloads = async (version: string, stats: Stats): Promise<void> => {
const requests: Promise<unknown>[] = [];
for (let i = 0; i < getConfig().maxConcurrentDownloads; i++) {
requests.push(downloadPackage(version, stats));
}
await Promise.all(requests);
if (stats.successfulDownloads < getConfig().numDownloads) {
await spamDownloads(version, stats);
}
};
All of this is brought together using run()
, which is executed upon starting npm-downloads-increaser
.
setInterval(() => logDownload(stats), 1000)
will update the console with the package download statistics every 1000ms. These statistics include:
- Download count
- Download speed
- Estimated time remaining
const run = async (): Promise<void> => {
try {
const npmsResponse: NpmjsResponse = await queryNpms();
const version: string = npmsResponse.collected.metadata.version;
const startTime = Date.now();
const stats: Stats = new Stats(startTime);
const loggingInterval: NodeJS.Timeout = setInterval(() => logDownload(stats), 1000);
await spamDownloads(version, stats);
clearInterval(loggingInterval);
logComplete();
} catch (e) {
logError(e);
}
};
Demo
View this package on npmJS here, or check out the source code here.