Built-in Middleware
Modern Express ships with a small set of built-in middleware — no install required, available as express.something(). They cover the most universal needs: parsing JSON and form bodies, and serving static files. Knowing exactly what each does (and its key options) means you configure them correctly instead of cargo-culting a config from a tutorial.
The built-in set
Middleware | Purpose |
|---|---|
| Parse JSON request bodies → |
| Parse HTML form bodies → |
| Serve static files from a directory |
| Body as a raw |
| Body as a plain string |
express.json()
app.use(express.json({
limit: '1mb', // reject bodies larger than this (DoS guard)
strict: true, // only accept arrays/objects (default)
type: 'application/json', // which Content-Type to parse
}))
app.post('/data', (req, res) => {
res.json({ received: req.body }) // req.body is the parsed object
})express.urlencoded()
// For HTML form submissions (application/x-www-form-urlencoded):
app.use(express.urlencoded({ extended: true, limit: '1mb' }))
// <form method="post"> with name="email" → req.body.emailexpress.static()
Covered in depth on its own page — it safely serves files from a directory with correct MIME types, caching, and path-traversal protection:
import { join } from 'node:path'
app.use(express.static(join(import.meta.dirname, 'public'), { maxAge: '1d' }))express.raw() and express.text()
Two specialized parsers. express.raw() gives the body as a Buffer — essential for webhook signature verification, where you need the exact bytes. express.text() gives a string.
// Webhook: verify a signature over the RAW bytes, so parse as Buffer:
app.post('/webhook',
express.raw({ type: 'application/json' }),
(req, res) => {
const valid = verifySignature(req.body, req.get('X-Signature')) // req.body is a Buffer
if (!valid) return res.sendStatus(401)
const event = JSON.parse(req.body.toString('utf8'))
handle(event)
res.sendStatus(200)
})Apply parsers globally vs per-route
// Global JSON parsing for the whole API:
app.use(express.json())
// ...but the webhook route overrides with raw parsing:
app.post('/webhook', express.raw({ type: '*/*' }), webhookHandler)