Send a JSON response using Express
By Flavio Copes
Return JSON from Express with res.json(): send arrays and error objects, set status codes, and handle dates, undefined values, and serialization errors.
To send a JSON response in Express, call res.json() in your route handler, passing an object or array. Express serializes it and sends it to the client.
Pass JavaScript data directly. Express uses JSON.stringify() to serialize it (you can inspect the result with my JSON formatter):
app.get('/user', (req, res) => {
res.json({ username: 'Flavio' })
})
The client receives this body:
{"username":"Flavio"}
res.json() also sets the Content-Type header to application/json, so the client knows to parse the response as JSON. With res.send() and a string you’d get text/html instead.
How do you set the status code?
Chain res.status() before it:
app.get('/user/:id', async (req, res) => {
const user = await findUser(req.params.id)
if (!user) {
return res.status(404).json({ error: 'User not found' })
}
res.json(user)
})
Without an explicit status, Express sends 200.
The return in the error branch stops the handler after sending the 404. For other response methods and the double-response error, see sending a response with Express.
Send arrays and empty results
An endpoint returning a list can send an array directly:
app.get('/users', (req, res) => {
res.json([{ username: 'Flavio' }])
})
If there are no results, res.json([]) sends an empty JSON array. A 204 No Content response has no body, so use it only when the client should not receive JSON.
Don’t stringify the data first
Give res.json() the object itself. Passing a JSON string serializes that string again:
const user = { username: 'Flavio' }
JSON.stringify(user) //'{"username":"Flavio"}'
JSON.stringify(JSON.stringify(user)) //'"{\"username\":\"Flavio\"}"'
With the second result, a client’s JSON parser returns a string rather than a user object.
Know what JSON can represent
Dates become strings, and object properties set to undefined disappear:
const user = {
username: 'Flavio',
joinedAt: new Date('2026-01-01T00:00:00Z'),
nickname: undefined
}
JSON.stringify(user)
//'{"username":"Flavio","joinedAt":"2026-01-01T00:00:00.000Z"}'
Use null when the response should explicitly include an empty field. Convert a BigInt to a string before returning it, and avoid circular references: both make serialization throw by default. The JSON.stringify() reference covers these rules.
Want me to talk about your product? You can sponsor this site.