Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

Express.js · Module

res.download

res.download() transfers a file as an attachment and usually prompts the browser to download it. It can customize the displayed filename, forward file-serving options, and report completion or errors through a callback.

Since
v4.16.0

How it works

res.download() transfers a file as an attachment, causing browsers to normally offer it for download. You can replace the displayed filename, configure send-file behavior through options, and receive a callback after completion or failure; callback error handling must account for responses that may already be partly sent.

Syntax

res.download(path, [filename], [options], [fn])

Parameters

NameTypeDescription
pathStringPath of the file to transfer; a relative path uses the current working directory or root.
filenameString | undefinedOptional Content-Disposition filename, overriding the name derived from path.
optionsObject | undefinedOptional settings forwarded to res.sendFile(); added in Express 4.16.0.
fnFunctionOptional callback invoked as fn(err) when transfer completes or fails.

Returns

The page documents the transfer behavior and callback, but does not specify a return value.

Key points

  • The method sends the selected file as an attachment rather than an inline response.
  • Clients commonly display a save/download prompt after receiving the response.
  • Without filename, the download name is inferred from the path.
  • Pass filename to choose the name shown to the downloading client.
  • The options object reuses the file-serving configuration supported by res.sendFile().
  • The callback receives an error value when the transfer fails and is also called after successful completion.

Common mistakes

  • When using the callback, an error does not automatically finish request handling: end the response or pass control to the next middleware.
  • A failed transfer can leave part of the response sent, so inspect res.headersSent before attempting another response.
  • A relative path is not relative to the route file; it resolves from the process working directory unless root is supplied.

Example: Download a report

const express = require('express');
const path = require('node:path');

const app = express();

app.get('/reports/latest', (req, res, next) => {
  res.download(
    path.join(__dirname, 'files', 'report.pdf'),
    'latest-report.pdf',
    (err) => {
      if (err) return next(err);
      console.log('download complete');
    }
  );
});

app.listen(3000);

This route sends a PDF as an attachment and supplies the browser-facing filename. The callback handles completion and forwards transfer errors.

When to use it

Download a report

A route serves generated or stored reports while giving the browser a stable download name.

Serve files from a controlled root

An endpoint exposes a file from a configured directory using root-based relative paths.

Track completed downloads

A handler needs to perform cleanup or accounting after transfer completion.

Interview questions

QWhat does res.download() do, and why provide filename?

It sends the file at path with attachment semantics, so browsers typically prompt for a download. The optional filename changes the Content-Disposition filename without changing the source path.

Follow-up: How would you constrain relative paths? Supply the root option and use a relative path; Express validates the path against that root.

QHow does the options argument affect a download?

The options object is forwarded to res.sendFile(). Its documented settings include values such as maxAge and root, and the options parameter was added in Express 4.16.0.

Follow-up: What does maxAge control? It sets the max-age value of Cache-Control, accepting milliseconds as a number or an ms-format string.

QHow should callback errors be handled?

The callback receives err after the transfer completes or an error occurs. With a callback, an error must be handled explicitly by ending the response or passing control to the next route or middleware.

Follow-up: What response-state issue can occur after failure? The response may be partially sent, so check res.headersSent before continuing response handling.

  • res.sendFile()
  • res.headersSent
  • res.set()

Source: Response - Express.js 4.x. Checked 2026-10-15.