You can download a file (an image, a text, or any kind of file) and save it to your filesystem using NodeJS built-in https
and fs
module.
The https
module allows you to create an HTTPS request using NodeJS, while the fs
module grants you access to the filesystem.
By combining both modules, you can create an HTTPS GET request and write the response stream as a new file in your filesystem.
First, create a new file named download.js
and import both modules to your script using the require()
method as follows:
const https = require("https");
const fs = require("fs");
Then, create a url
string to a file that can be accessed on the internet publicly.
For example, I’m going to try and download a .png
picture from my website here:
const url = "sebhastian.com/img/default.png";
Next, call the https.get()
method and pass the url
variable as its first argument. The second argument of the method will be the callback
function you want to run once a response stream has been received:
https.get(url, (res) => {
// TODO: create a writable stream
// and save the received data stream
});
Inside the callback
function, write the name for the file you’re going to save as a path
variable. For example, I want to save the image and name it as downloaded-image.png"
:
https.get(url, (res) => {
const path = "downloaded-image.png";
});
Now you need to create a new writable stream using fs.createWriteStream()
method and pass the path
variable as its argument. The fs
module will create the writable stream on the current folder by default:
https.get(url, (res) => {
const path = "downloaded-image.png";
const writeStream = fs.createWriteStream(path);
});
Finally, send the GET
response data stream to the writeStream
object using the pipe()
method. When the writeStream
sends the finish
signal, close the writeStream
object:
https.get(url, (res) => {
const path = "downloaded-image.png";
const writeStream = fs.createWriteStream(path);
res.pipe(writeStream);
writeStream.on("finish", () => {
writeStream.close();
console.log("Download Completed");
});
});
The complete JavaScript code is as shown below:
const https = require("https");
const fs = require("fs");
// URL of the image
const url = "sebhastian.com/img/default.png";
https.get(url, (res) => {
const path = "downloaded-image.png";
const writeStream = fs.createWriteStream(path);
res.pipe(writeStream);
writeStream.on("finish", () => {
writeStream.close();
console.log("Download Completed");
});
});
You can execute the script using node
command to see it in action:
node download
Additionally, you can also provide two command-line arguments to the script as follows:
- The first argument will be the URL to the file you want to download
- The second argument will be the name of file that will be saved to your file system
You can get the command-line arguments from the process.argv
property and stop the script when the user doesn’t pass both arguments to the script:
const { argv } = process;
const [, , url, path] = argv;
if (url === undefined) {
console.log(`The 'url' argument is missing.
You need to pass the file url as the first argument`);
return;
}
if (path === undefined) {
console.log(`The 'path' argument is missing.
You need to pass the save path as the second argument`);
return;
}
Pass the code above just below the imports as follows:
const https = require("https");
const fs = require("fs");
const { argv } = process;
const [, , url, path] = argv;
if (url === undefined) {
console.log(`The 'url' argument is missing.
You need to pass the file url as the first argument`);
return;
}
if (path === undefined) {
console.log(`The 'path' argument is missing.
You need to pass the save path as the second argument`);
return;
}
https.get(url, (res) => {
const writeStream = fs.createWriteStream(path);
res.pipe(writeStream);
writeStream.on("finish", () => {
writeStream.close();
console.log("Download Completed");
});
});
With that, you can reuse the download.js
file to download a file from a URL. Each time you execute the script, pass the required url
and path
arguments from the command-line.
The example below will download the image from the first argument as save it as image.png
:
node download sebhastian.com/img/default.png image.png
And that’s how you can download a file using NodeJS without installing any extra package.
Bonus: download multiple files using NodeJS
Sometimes, you may need to download multiple files and save them into your system.
I’d recommend you use the npm download
package instead of writing your own code.
The download
package allows you to download multiple images and save them under a folder as shown below:
const download = require("download");
(async () => {
await Promise.all(
[
"sebhastian.com/img/default.png",
"sebhastian.com/img/nathan-sebhastian.png",
].map((url) => download(url, "dist"))
);
})();
The code above saves both default.png
and nathan-sebhastian.png
files to the ./dist
folder. Check out download
npm page for more information.