How to download a file using NodeJS without any extra package

Download a file to your filesystem using NodeJS without any extra package

Posted on June 26, 2021


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.

Related articles:

Level up your programming skills

I'm sending out an email once every Wednesday with the latest programming tutorials. Drop your email in the box below and I'll send new stuff straight into your inbox!

No spam. Unsubscribe anytime.