Express Cheatsheet
The Response Object
Use this Express reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Overview
The res object is a Node.js ServerResponse extended with Express helpers. Call exactly one response-ending method per request; calling more causes Cannot set headers after they are sent errors.
Sending Responses
res.send()
Sends a response. Sets Content-Type automatically based on argument type.
res.send('Hello'); // text/html res.send('<h1>Hello</h1>'); // text/html res.send({ key: 'value' }); // application/json (deprecated — prefer res.json) res.send(Buffer.from('binary')); // application/octet-stream res.send(); // 204 No Content (no body)
res.json()
Serializes value with JSON.stringify, sets Content-Type: application/json. Respects json spaces and json replacer app settings.
res.json({ user: 'Alice', age: 30 }); res.json([1, 2, 3]); res.json(null); // valid JSON null res.status(201).json(created);
res.jsonp()
Like res.json() but wraps in a JSONP callback.
// GET /data?callback=myFunc res.jsonp({ value: 42 }); // → myFunc({"value":42})
res.sendStatus()
Set status and send its string representation as the body.
res.sendStatus(200); // 'OK' res.sendStatus(201); // 'Created' res.sendStatus(204); // 'No Content' res.sendStatus(404); // 'Not Found' res.sendStatus(500); // 'Internal Server Error'
res.end()
Node's low-level method — finishes response with no processing.
res.end(); // no body res.end('done'); // raw string, no Content-Type set
Status Codes — res.status()
Chainable setter. Returns res for chaining.
res.status(404).json({ error: 'Not found' }); res.status(201).send('Created'); res.status(400).end();
Redirects — res.redirect()
res.redirect('/new-path'); // 302 (temporary, default) res.redirect(301, '/permanent'); // 301 permanent res.redirect(307, '/temp'); // 307 preserves method res.redirect(308, '/permanent'); // 308 preserves method + permanent res.redirect('back'); // redirect to Referer header (or '/') res.redirect('..'); // one level up res.redirect('https://example.com'); // absolute URL
Sending Files — res.sendFile() / res.download()
// res.sendFile — serve a file, Content-Type from extension res.sendFile('/absolute/path/to/file.pdf'); res.sendFile(path.join(__dirname, 'public', 'index.html')); // With options res.sendFile('/path/to/file', { maxAge: '1d', // cache max-age root: __dirname, // allows relative path dotfiles: 'deny', // 'allow', 'deny', 'ignore' headers: { 'X-Custom': 'value' }, }, (err) => { if (err) next(err); }); // res.download — sets Content-Disposition: attachment (triggers browser download) res.download('/path/to/report.pdf'); res.download('/path/to/report.pdf', 'my-report.pdf'); // custom filename res.download('/path/to/report.pdf', 'my-report.pdf', (err) => { if (err) next(err); });
Rendering Views — res.render()
app.set('view engine', 'ejs'); app.set('views', path.join(__dirname, 'views')); res.render('index'); // views/index.ejs res.render('user/profile', { user: req.user }); // pass locals res.render('page', locals, (err, html) => { // callback — don't send yet if (err) return next(err); res.send(html); });
Setting Headers — res.set() / res.get() / res.removeHeader()
res.set('X-Custom-Header', 'value'); res.set({ 'X-Foo': 'bar', 'X-Baz': 'qux' }); // object form res.header('X-Custom', 'value'); // alias for res.set() res.get('Content-Type'); // read a set header (before sending) res.removeHeader('X-Powered-By');
Content-Type — res.type()
Sets Content-Type from a MIME type string or file extension.
res.type('html'); // text/html; charset=utf-8 res.type('json'); // application/json res.type('png'); // image/png res.type('text/plain'); // explicit MIME type res.type('application/octet-stream');
Streaming — res.write() / res.end()
For streaming large responses or Server-Sent Events.
// Manual streaming res.set('Content-Type', 'text/plain'); res.write('chunk 1\n'); res.write('chunk 2\n'); res.end(); // Pipe a readable stream const fs = require('fs'); fs.createReadStream('large-file.csv').pipe(res); // Server-Sent Events res.set({ 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', }); res.flushHeaders(); const id = setInterval(() => { res.write(`data: ${JSON.stringify({ time: Date.now() })}\n\n`); }, 1000); req.on('close', () => clearInterval(id));
Locals — res.locals
Variables available to templates rendered during the request lifetime.
// Set in middleware app.use((req, res, next) => { res.locals.user = req.user; res.locals.csrfToken = req.csrfToken?.(); next(); }); // Available in all res.render() calls automatically res.render('dashboard'); // template sees user, csrfToken
Link and Location Headers — res.links() / res.location()
// Set Link header (used for pagination) res.links({ next: '/items?page=2', prev: '/items?page=0', last: '/items?page=10', }); // → Link: </items?page=2>; rel="next", </items?page=0>; rel="prev", ... // Set Location header (without redirecting) res.location('/new-resource'); res.location('https://example.com');
Vary Header — res.vary()
res.vary('Accept'); // Vary: Accept res.vary('Accept-Encoding');
Quick Method Reference
| Method | Response ends? | Description |
|---|---|---|
res.send(body) | Yes | Send any body |
res.json(obj) | Yes | JSON response |
res.jsonp(obj) | Yes | JSONP response |
res.sendStatus(code) | Yes | Status + status text body |
res.redirect([code,] url) | Yes | HTTP redirect |
res.sendFile(path) | Yes | Stream a file |
res.download(path) | Yes | Force-download file |
res.render(view, locals) | Yes | Render template |
res.end([data]) | Yes | Low-level end |
res.write(chunk) | No | Stream chunk |
res.status(code) | No | Set status code (chainable) |
res.set(field, val) | No | Set response header |
res.get(field) | No | Read a set header |
res.type(type) | No | Set Content-Type |
res.cookie(name, val) | No | Set cookie |
res.clearCookie(name) | No | Clear cookie |
res.location(url) | No | Set Location header |
res.links(links) | No | Set Link header |
res.vary(field) | No | Append to Vary header |
res.attachment([file]) | No | Set Content-Disposition |
res.append(field, val) | No | Append to header |