Stream File Downloads with Axios in Node.js

Downloading large files into memory before saving them can lead to high memory consumption and application crashes in Node.js. The most efficient way to handle file downloads is to stream the incoming HTTP response directly to the local filesystem using Axios and the native fs module. This approach processes the data in chunks, keeping memory usage minimal regardless of the file size.

Prerequisites

To implement streaming downloads, install Axios in your project:

npm install axios

Complete Code Implementation

The following example demonstrates how to download a file and write it directly to the local disk using Axios and Node.js stream pipelines.

const fs = require('node:fs');
const { pipeline } = require('node:stream/promises');
const axios = require('axios');

async function downloadFile(fileUrl, outputLocationPath) {
  try {
    // Request the file with responseType set to 'stream'
    const response = await axios({
      method: 'get',
      url: fileUrl,
      responseType: 'stream',
    });

    // Create a writable stream to the destination file
    const writer = fs.createWriteStream(outputLocationPath);

    // Pipe the response stream directly to the file system
    await pipeline(response.data, writer);

    console.log('Download completed successfully.');
  } catch (error) {
    console.error('Download failed:', error.message);
    throw error;
  }
}

// Example usage
const url = 'https://example.com/large-file.zip';
const outputPath = './large-file.zip';

downloadFile(url, outputPath);

Key Components Explained

  1. responseType: 'stream': By default, Axios parses the response as JSON or text. Setting responseType: 'stream' instructs Axios to return the raw Node.js Readable stream in response.data.
  2. fs.createWriteStream(): Initializes a Writable stream pointing to the destination path on the local filesystem.
  3. stream/promises pipeline: The pipeline method pipes the readable stream from Axios into the writable file stream. Using the promise-based pipeline ensures proper error handling, cleanup of open file descriptors if the download fails, and easy integration with async/await.