Gathering detailed insights and metrics for nodejs-file-downloader
Gathering detailed insights and metrics for nodejs-file-downloader
Gathering detailed insights and metrics for nodejs-file-downloader
Gathering detailed insights and metrics for nodejs-file-downloader
npm install nodejs-file-downloader
Typescript
Module System
Node Version
NPM Version
97.8
Supply Chain
100
Quality
77.6
Maintenance
100
Vulnerability
99.3
License
JavaScript (98.94%)
TypeScript (1.06%)
Total Downloads
5,815,019
Last Day
8,868
Last Week
54,630
Last Month
247,559
Last Year
2,288,594
135 Stars
125 Commits
23 Forks
4 Watchers
12 Branches
7 Contributors
Updated on Apr 23, 2025
Minified
Minified + Gzipped
Latest Version
4.13.0
Package Id
nodejs-file-downloader@4.13.0
Unpacked Size
198.35 kB
Size
108.56 kB
File Count
24
NPM Version
10.1.0
Node Version
20.9.0
Published on
Jun 07, 2024
Cumulative downloads
Total Downloads
Last Day
-7%
8,868
Compared to previous day
Last Week
-6.9%
54,630
Compared to previous week
Last Month
3.5%
247,559
Compared to previous month
Last Year
32.3%
2,288,594
Compared to previous year
8
nodejs-file-downloader is a simple utility for downloading files. It hides the complexity of dealing with streams, redirects, paths and duplicate file names. Can automatically repeat failed downloads.
In case you encounter any bugs or have a question, please don't hesitate to open an issue.
If you like the program and want to support me for my work, you can buy me ☕
1$ npm install nodejs-file-downloader
Download a large file with default configuration
1const {Downloader} = require("nodejs-file-downloader"); 2 3(async () => { 4 //Wrapping the code with an async function, just for the sake of example. 5 6 const downloader = new Downloader({ 7 url: "http://212.183.159.230/200MB.zip", //If the file name already exists, a new file with the name 200MB1.zip is created. 8 directory: "./downloads", //This folder will be created, if it doesn't exist. 9 }); 10 try { 11 const {filePath,downloadStatus} = await downloader.download(); //Downloader.download() resolves with some useful properties. 12 13 console.log("All done"); 14 } catch (error) { 15 //IMPORTANT: Handle a possible error. An error is thrown in case of network errors, or status codes of 400 and above. 16 //Note that if the maxAttempts is set to higher than 1, the error is thrown only if all attempts fail. 17 console.log("Download failed", error); 18 } 19})();
If the response headers contain information about the file size, onProgress hook can be used. If the file size cannot be determined, "percentage" and "remainingSize" arguments will be called with NaN.
1const {Downloader} = require("nodejs-file-downloader"); 2 3(async () => { 4 const downloader = new Downloader({ 5 url: "http://212.183.159.230/200MB.zip", 6 directory: "./downloads/2020/May", //Sub directories will also be automatically created if they do not exist. 7 onProgress: function (percentage, chunk, remainingSize) { 8 //Gets called with each chunk. 9 console.log("% ", percentage); 10 console.log("Current chunk of data: ", chunk); 11 console.log("Remaining bytes: ", remainingSize); 12 }, 13 }); 14 15 try { 16 await downloader.download(); 17 } catch (error) { 18 console.log(error); 19 } 20})();
If you haven't supplied a "fileName" config property, the program will try its best to choose the most appropriate name for the file(from the URL, headers, etc). In case you wish to know the name that was chosen, before the file is actually saved, use the onBeforeSave hook, which is called with the deduced name. If you're "unhappy" with the name, it can be overridden by returning a new string. Returning anything else(including undefined/void), will let the program know that it can keep the name.
1const downloader = new Downloader({ 2 url: "http://212.183.159.230/200MB.zip", 3 directory: "./downloads/2020/May", 4 onBeforeSave: (deducedName) => { 5 console.log(`The file name is: ${deducedName}`); 6 //If you return a string here, it will be used as the name(that includes the extension!). 7 }, 8});
Normally, nodejs-file-downloader "deduces" the file name, from the URL or the response headers. If you want to choose a custom file name, supply a config.fileName property.
1const downloader = new Downloader({ 2 url: "http://212.183.159.230/200MB.zip", 3 directory: "./downloads/2020/May", 4 fileName: "somename.zip", //This will be the file name. 5});
By default, nodejs-file-downloader uses config.cloneFiles = true, which means that files with an existing name, will have a number appended to them.
1const downloader = new Downloader({ 2 url: "http://212.183.159.230/200MB.zip", 3 directory: "./", 4 cloneFiles: false, //This will cause the downloader to re-write an existing file. 5});
If you want to completely skip downloading a file, when a file with the same name already exists, use config.skipExistingFileName = true
Just add a "headers" property to the config object:
1const downloader = new Downloader({ 2 url: "http://212.183.159.230/200MB.zip", 3 directory: "./", 4 headers: { 5 "Some-Header": value, 6 }, 7});
If you need to get the underlying response, in order to decide whether the download should continue, or perform any other operations, use the onReponse hook.
1//The response object is a node response(http.IncomingMessage) 2function onResponse(response) { 3 //Now you can do something with the response, like check the headers 4 if (response.headers["content-length"] > 1000000) { 5 console.log("File is too big!"); 6 return false; //If you return false, the download process is stopped, and downloader.download() is resolved. 7 } 8 9 //Returning any other value, including undefined, will tell the downloader to proceed as usual. 10} 11 12const downloader = new Downloader({ 13 url: "http://212.183.159.230/200MB.zip", 14 directory: "./", 15 onResponse, 16}); 17try { 18 await downloader.download(); 19} catch (error) { 20 console.log(error); 21}
The program can repeat any failed downloads automatically. Only if the provided config.maxAttempts number is exceeded, an Error is thrown.
1const downloader = new Downloader({ 2 url: "http://212.183.159.230/200MB.zip", 3 directory: "./", 4 maxAttempts: 3, //Default is 1. 5 onError: function (error) { 6 //You can also hook into each failed attempt. 7 console.log("Error from attempt ", error); 8 }, 9}); 10 11try { 12 await downloader.download(); 13} catch (error) { 14 //If all attempts fail, the last error is thrown. 15 console.log("Final fail", error); 16}
If you use the auto-repeat option, by setting the maxAttempts to greater than 1, "shouldStop" hook can be used, To decide whether the repetition should continue. This is useful in cases where you're generating many dynamic url's, some of which can result in a 404 http status code(for example), and there is no point in repeating that request.
1const downloader = new Downloader({ 2 url: "http://212.183.159.230/200MB.zip", 3 directory: "./", 4 maxAttempts: 3, //We set it to 3, but in the case of status code 404, it will run only once. 5 shouldStop: function (error) { 6 //A request that results in a status code of 400 and above, will throw an Error, that contains a custom property 7 //"statusCode". 8 9 //Note that an error that is thrown during the stream itself(after a valid http response was already received. It's quite rare, but happens), will not have a "statusCode" property. 10 if (e.statusCode && e.statusCode === 404) { 11 return true; //If you return true, the repetition will not happen. Returning anything else, including undefined, will let the downloader know that you want to continue repeating. 12 } 13 }, 14}); 15 16try { 17 await downloader.download(); 18} catch (error) { 19 //If all attempts fail, the last error is thrown. 20 console.log("Final fail", error); 21}
This feature is new. Kindly report any bugs you encounter. Useful for Electron apps.
1const downloader = new Downloader({ 2 url: "http://212.183.159.230/200MB.zip", 3 directory: "./", 4}); 5 6try { 7 //Mocking cancellation 8 setTimeout(() => { 9 downloader.cancel(); 10 }, 2000); 11 12 await downloader.download(); 13 14 //If the download is cancelled, the promise will not be resolved, so this part is never reached 15 console.log("done"); 16} catch (error) { 17 //When the download is cancelled, 'ERR_REQUEST_CANCELLED' error is thrown. This is how you can handle cancellations in your code. 18 if (error.code === "ERR_REQUEST_CANCELLED") { 19 //do something after cancellation.. 20 } else { 21 //handle general error.. 22 } 23}
You can pass a proxy string. Under the hood, this will create a custom httpsAgent. This feature wasn't tested extensively.
1const downloader = new Downloader({ 2 proxy: "http://username:password@some-proxy.com:22225", 3 url: "http://212.183.159.230/200MB.zip", 4 directory: "./", 5});
downloader.download() will throw an error, just like Axios, in case of network problems or an http status code of 400 or higher.
If the auto-repeat feature is enabled(by setting the maxAttempts to higher than 1), then only a failure of the final attempt will throw an error.
If a status code of 400 or above is received, the program throws an error. In this case, a reference to the response body will be available in error.responseBody:
1const downloader = new Downloader({ 2 url: "http://www.somesite.com/400", 3 directory: "./", 4}); 5 6try { 7 await downloader.download(); 8} catch (error) { 9 if (error.responseBody) { 10 console.log(error.responseBody) 11 } 12} 13
If you're getting a consistent ECONNRESET error, it's possible the server requires a User-Agent header to be sent. Try adding it:
1const downloader = new Downloader({ 2 url: "http://www.user-agent-required.com/", 3 directory: "./", 4 headers:{ 5 'User-Agent':'Some user agent..' 6 } 7}); 8 9
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
no dangerous workflow patterns detected
Reason
Found 2/24 approved changesets -- score normalized to 0
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
license file not detected
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
11 existing vulnerabilities detected
Details
Score
Last Scanned on 2025-04-28
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More