Express Cheatsheet
Body Parsing
Use this Express reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Built-in Parsers (Express 4.16+)
No external packages needed for JSON and URL-encoded bodies.
// Parse application/json app.use(express.json()); // Parse application/x-www-form-urlencoded (HTML forms) app.use(express.urlencoded({ extended: true })); // Parse raw Buffer body app.use(express.raw({ type: 'application/octet-stream' })); // Parse plain text body app.use(express.text({ type: 'text/plain' }));
After any of these, the parsed body is available on req.body.
express.json() Options
app.use(express.json({ limit: '100kb', // max body size (default '100kb') strict: true, // only accept arrays and objects (default true) type: 'application/json', // MIME types to parse (string, array, or function) reviver: null, // JSON.parse reviver function inflate: true, // handle deflated/gzip bodies }));
// Accept multiple content types app.use(express.json({ type: ['application/json', 'application/cjson'] })); // Custom reviver — convert ISO date strings to Date objects app.use(express.json({ reviver: (key, value) => { if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}T/.test(value)) return new Date(value); return value; } }));
express.urlencoded() Options
app.use(express.urlencoded({ extended: true, // true = qs (nested objects); false = querystring (flat) limit: '100kb', parameterLimit: 1000, // max number of parameters (default 1000) type: 'application/x-www-form-urlencoded', }));
extended: true (qs) supports nested objects:
// Form: filter[price][gte]=10&filter[price][lte]=100 req.body.filter.price.gte // '10'
extended: false (querystring) is flat:
// filter[price][gte]=10 → req.body['filter[price][gte]'] = '10'express.raw() Options
app.use(express.raw({ type: 'application/octet-stream', limit: '10mb', inflate: true, })); app.post('/upload', (req, res) => { req.body; // Buffer req.body.length; // byte count });
express.text() Options
app.use(express.text({ type: 'text/plain', defaultCharset: 'utf-8', limit: '100kb', })); app.post('/webhook', (req, res) => { typeof req.body; // 'string' });
Route-Scoped Parsing
Apply parsers only to specific routes to avoid overhead or to use different limits.
// High limit only for file endpoint app.post('/import', express.json({ limit: '10mb' }), (req, res) => { // large JSON allowed here only }); // Raw body for Stripe webhook (must NOT go through express.json first) app.post( '/webhook', express.raw({ type: 'application/json' }), (req, res) => { const sig = req.headers['stripe-signature']; const event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_SECRET); // req.body is a Buffer here } ); // JSON everywhere else app.use(express.json());
Stripe / webhook gotcha: raw body parsers must run before
express.json()on the webhook route. Mount the raw route before the global JSON middleware, or use a type discriminator.
Multipart / File Uploads — multer
express.json() does not handle multipart/form-data. Use multer.
const multer = require('multer'); // Memory storage (file in req.file.buffer) const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 5 * 1024 * 1024 } }); // Disk storage const disk = multer.diskStorage({ destination: (req, file, cb) => cb(null, './uploads'), filename: (req, file, cb) => cb(null, `${Date.now()}-${file.originalname}`), }); const uploadDisk = multer({ storage: disk }); // Single file router.post('/avatar', upload.single('avatar'), (req, res) => { req.file; // { fieldname, originalname, mimetype, buffer, size } req.body; // other form fields }); // Multiple files, same field router.post('/photos', upload.array('photos', 5), (req, res) => { req.files; // array }); // Multiple fields router.post('/form', upload.fields([ { name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 10 }, ]), (req, res) => { req.files.avatar[0]; // single avatar file req.files.gallery; // array }); // No file — just multipart form fields router.post('/form', upload.none(), (req, res) => { req.body; // parsed fields });
multer File Object Properties
| Property | Description |
|---|---|
fieldname | Field name from the form |
originalname | Original filename from client |
encoding | File encoding |
mimetype | MIME type |
size | Size in bytes |
buffer | Buffer (memoryStorage only) |
path | Saved path (diskStorage only) |
filename | Saved filename (diskStorage only) |
destination | Directory (diskStorage only) |
File Type Validation with multer
const upload = multer({ fileFilter: (req, file, cb) => { const allowed = ['image/jpeg', 'image/png', 'image/webp']; if (!allowed.includes(file.mimetype)) { return cb(new Error('Only JPEG, PNG, and WebP allowed')); } cb(null, true); }, limits: { fileSize: 2 * 1024 * 1024 }, // 2 MB });
Checking req.body is Populated
app.post('/data', express.json(), (req, res) => { if (!req.body || Object.keys(req.body).length === 0) { return res.status(400).json({ error: 'Empty body' }); } // ... });
Body Size Limit Errors
When the body exceeds the limit, Express emits a PayloadTooLargeError. Catch it in your error handler:
app.use((err, req, res, next) => { if (err.type === 'entity.too.large') { return res.status(413).json({ error: 'Payload too large' }); } next(err); });
Unsupported Media Type
When a client sends an unrecognized Content-Type and no parser handles it, req.body is undefined. Respond with 415:
app.post('/data', express.json(), (req, res) => { if (req.body === undefined) { return res.status(415).json({ error: 'Unsupported Media Type' }); } });