Skip to main content

Overview

The res object represents the HTTP response that an Express app sends when it gets an HTTP request. By convention, the object is always referred to as res (and the HTTP request is req).
app.get('/user/:id', (req, res) => {
  res.send(`User ${req.params.id}`);
});
The response object is an enhanced version of Node’s built-in http.ServerResponse object.

Properties

res.app

Reference to the Express application instance.
app.get('/', (req, res) => {
  console.log(res.app.get('title')); // "My App"
});

res.headersSent

Boolean indicating if the app sent HTTP headers for the response.
app.get('/', (req, res) => {
  console.log(res.headersSent); // false
  res.send('OK');
  console.log(res.headersSent); // true
});

res.locals

An object that contains response local variables scoped to the request. Available only to the views rendered during that request-response cycle.
app.use((req, res, next) => {
  res.locals.user = req.user;
  res.locals.authenticated = !req.user.anonymous;
  next();
});

app.get('/', (req, res) => {
  res.render('index'); // user and authenticated available in template
});

res.req

Reference to the request object.
app.get('/', (req, res) => {
  console.log(res.req === req); // true
});

Methods

res.append(field, value)

Appends the specified value to the HTTP response header. If the header is not already set, it creates the header with the specified value.
field
string
required
The header field name
value
string | array
required
The value to append
res.append('Link', ['<http://localhost/>', '<http://localhost:3000/>']);
res.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly');
res.append('Warning', '199 Miscellaneous warning');

res.attachment([filename])

Sets the HTTP response Content-Disposition header to “attachment”. If a filename is given, it sets the Content-Type based on the extension.
filename
string
The filename for the attachment
res.attachment();
// Content-Disposition: attachment

res.attachment('path/to/logo.png');
// Content-Disposition: attachment; filename="logo.png"
// Content-Type: image/png
Sets a cookie with the specified name and value.
name
string
required
The cookie name
value
string | object
required
The cookie value (objects are JSON-stringified)
options
object
Cookie options
Options:
  • domain - Domain name for the cookie
  • expires - Expiry date (GMT). If not specified, creates a session cookie
  • httpOnly - Makes cookie inaccessible to client-side JavaScript
  • maxAge - Expiry time relative to current time in milliseconds
  • path - Cookie path (default: /)
  • secure - Marks cookie for HTTPS only
  • signed - Indicates if cookie should be signed
  • sameSite - Value of “SameSite” Set-Cookie attribute
res.cookie('name', 'tobi', { 
  domain: '.example.com', 
  path: '/admin', 
  secure: true 
});

res.cookie('rememberme', '1', { 
  expires: new Date(Date.now() + 900000), 
  httpOnly: true 
});

// maxAge example (15 minutes)
res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true });

// JSON cookie
res.cookie('cart', { items: [1, 2, 3] });

res.clearCookie(name, [options])

Clears the cookie specified by name.
name
string
required
The cookie name to clear
options
object
Cookie options (must match the options used in res.cookie())
res.cookie('name', 'tobi', { path: '/admin' });
res.clearCookie('name', { path: '/admin' });
Web browsers and other compliant clients will only clear cookies if the options match those given to res.cookie(), excluding expires and maxAge.

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

Transfers the file at path as an “attachment” with the optional filename. Automatically sets the Content-Disposition header.
path
string
required
The path to the file to download
filename
string
The filename for the download
options
object
Options to pass to res.sendFile()
callback
function
Callback function with signature (err)
res.download('/report-12345.pdf');

res.download('/report-12345.pdf', 'report.pdf');

res.download('/report-12345.pdf', 'report.pdf', (err) => {
  if (err) {
    // Handle error, but note that response may be partially sent
  } else {
    // Decrement download count, etc.
  }
});

res.end([data], [encoding])

Ends the response process. Use to quickly end the response without any data.
data
string | buffer
Data to send
encoding
string
Encoding of the data
res.end();
res.status(404).end();
This method comes from Node.js core, specifically the response.end() method of http.ServerResponse.

res.format(object)

Performs content-negotiation based on the Accept HTTP header. Uses req.accepts() to select a handler for the request.
object
object
required
Object with MIME types as keys and handler functions as values
res.format({
  'text/plain': () => {
    res.send('hey');
  },
  
  'text/html': () => {
    res.send('<p>hey</p>');
  },
  
  'application/json': () => {
    res.send({ message: 'hey' });
  },
  
  default: () => {
    // log the request and respond with 406
    res.status(406).send('Not Acceptable');
  }
});
You can also use extension names:
res.format({
  text: () => {
    res.send('hey');
  },
  
  html: () => {
    res.send('<p>hey</p>');
  },
  
  json: () => {
    res.send({ message: 'hey' });
  }
});

res.get(field)

Returns the HTTP response header specified by field. The match is case-insensitive.
field
string
required
The header field name
res.get('Content-Type'); // => "text/plain"

res.json([body])

Sends a JSON response. Automatically sets the Content-Type header to application/json.
body
any
The data to send as JSON
res.json(null);
res.json({ user: 'tobi' });
res.status(500).json({ error: 'message' });

res.jsonp([body])

Sends a JSON response with JSONP support. Identical to res.json() except it opts-in to JSONP callback support.
body
any
The data to send as JSONP
res.jsonp(null);
res.jsonp({ user: 'tobi' });
res.status(500).jsonp({ error: 'message' });
Example:
// ?callback=foo
res.jsonp({ user: 'tobi' });
// => foo({ "user": "tobi" })

app.set('jsonp callback name', 'cb');

// ?cb=foo
res.jsonp(500, { error: 'message' });
// => foo({ "error": "message" })
Sets the Link HTTP header with the provided links object.
Object with link relations as keys and URLs as values
res.links({
  next: 'http://api.example.com/users?page=2',
  last: 'http://api.example.com/users?page=5'
});
Produces:
Link: <http://api.example.com/users?page=2>; rel="next",
      <http://api.example.com/users?page=5>; rel="last"

res.location(path)

Sets the response Location HTTP header to the specified path.
path
string
required
The location URL
res.location('/foo/bar');
res.location('http://example.com');
res.location('../login');
res.location('back'); // Referer header or '/'
Express passes the specified URL string as-is to the browser without validation or manipulation (except for back).

res.redirect([status], path)

Redirects to the URL with an optional status code (default: 302).
status
number
HTTP status code (default: 302)
path
string
required
The URL to redirect to
res.redirect('/foo/bar');
res.redirect('http://example.com');
res.redirect(301, 'http://example.com');
res.redirect('../login');
res.redirect('back'); // Redirects to Referer or '/'
res.redirect('/admin');

res.render(view, [locals], [callback])

Renders a view template and sends the rendered HTML string to the client.
view
string
required
The name of the view file to render
locals
object
An object whose properties define local variables for the view
callback
function
Callback function with signature (err, html)
// Send the rendered view to the client
res.render('index');

// Pass local variables to the view
res.render('user', { name: 'Tobi' }, (err, html) => {
  if (err) {
    return next(err);
  }
  res.send(html);
});
The callback is optional. If provided, you must explicitly send the response. Otherwise, res.render() sends the response automatically.

res.send([body])

Sends the HTTP response. The body parameter can be a Buffer, String, Object, Boolean, or Array.
body
any
The data to send
res.send(Buffer.from('whoop'));
res.send({ some: 'json' });
res.send('<p>some html</p>');
res.status(404).send('Sorry, we cannot find that!');
res.status(500).send({ error: 'something blew up' });
Automatic Content-Type:
  • Buffer → application/octet-stream
  • String → text/html
  • Object/Array → application/json
  • Boolean/Number → application/json

res.sendFile(path, [options], [callback])

Transfers the file at the given path. Sets the Content-Type response header based on the filename’s extension.
path
string
required
The path to the file (must be absolute unless root option is provided)
options
object
Options object
callback
function
Callback function with signature (err)
Options:
  • maxAge - Sets the max-age property of the Cache-Control header in milliseconds
  • root - Root directory for relative filenames
  • lastModified - Sets the Last-Modified header (default: enabled)
  • headers - Object containing HTTP headers to serve with the file
  • dotfiles - Option for serving dotfiles. Values: ‘allow’, ‘deny’, ‘ignore’ (default: ‘ignore’)
app.get('/file/:name', (req, res, next) => {
  const options = {
    root: path.join(__dirname, 'public'),
    dotfiles: 'deny',
    headers: {
      'x-timestamp': Date.now(),
      'x-sent': true
    }
  };

  const fileName = req.params.name;
  res.sendFile(fileName, options, (err) => {
    if (err) {
      next(err);
    } else {
      console.log('Sent:', fileName);
    }
  });
});
The path must be absolute unless the root option is specified. Use path.join() or path.resolve() to construct absolute paths.

res.sendStatus(statusCode)

Sets the response status code and sends its string representation as the response body.
statusCode
number
required
The HTTP status code
res.sendStatus(200); // equivalent to res.status(200).send('OK')
res.sendStatus(403); // equivalent to res.status(403).send('Forbidden')
res.sendStatus(404); // equivalent to res.status(404).send('Not Found')
res.sendStatus(500); // equivalent to res.status(500).send('Internal Server Error')

res.set(field, [value])

Sets the response’s HTTP header field to value. To set multiple fields at once, pass an object.
field
string | object
required
The header field name or an object of headers
value
string | array
The value to set (can be array for multiple values)
res.set('Content-Type', 'text/plain');

res.set({
  'Content-Type': 'text/plain',
  'Content-Length': '123',
  'ETag': '12345'
});
Alias: res.header(field, [value])

res.status(code)

Sets the HTTP status code for the response.
code
number
required
The HTTP status code (100-999)
res.status(200).send('OK');
res.status(404).send('Not Found');
res.status(500).json({ error: 'Internal Server Error' });

res.type(type)

Sets the Content-Type HTTP header to the MIME type determined by the specified type.
type
string
required
The MIME type or file extension
res.type('.html');              // => 'text/html'
res.type('html');               // => 'text/html'
res.type('json');               // => 'application/json'
res.type('application/json');   // => 'application/json'
res.type('png');                // => 'image/png'
Alias: res.contentType(type)

res.vary(field)

Adds the field to the Vary response header, if it’s not already there.
field
string | array
required
The header field name(s)
res.vary('User-Agent');
res.vary(['User-Agent', 'Accept-Encoding']);

Response Status Codes

Common HTTP status codes:
  • 200 - OK
  • 201 - Created
  • 204 - No Content

Common Patterns

JSON API Response

app.get('/api/users/:id', (req, res) => {
  User.findById(req.params.id, (err, user) => {
    if (err) {
      return res.status(500).json({ error: 'Database error' });
    }
    if (!user) {
      return res.status(404).json({ error: 'User not found' });
    }
    res.json(user);
  });
});

File Download

app.get('/download/:file', (req, res) => {
  const file = `${__dirname}/files/${req.params.file}`;
  res.download(file, (err) => {
    if (err) {
      res.status(500).send('Error downloading file');
    }
  });
});

Content Negotiation

app.get('/user', (req, res) => {
  res.format({
    html: () => {
      res.render('user', { name: 'John' });
    },
    json: () => {
      res.json({ name: 'John' });
    }
  });
});

Build docs developers (and LLMs) love