Middleware functions have access to req, res, and next(). They can modify the request/response objects or end the cycle. Execution order matters — define middleware before routes.
Error-handling middleware requires four parameters: (err, req, res, next). Express uses function arity to distinguish error handlers from regular middleware.
Advanced patterns: middleware factories (function that returns middleware), conditional middleware (run based on route), and middleware composition with compose().
Body parsing: express.json() for JSON, express.urlencoded() for forms. File uploads: multer. Security: helmet, cors, express-rate-limit. Logging: morgan, winston.
Third-party middleware: passport for authentication, compression for gzip, express-validator for input validation. Always check middleware compatibility with your Express version.
Async middleware: wrap async handlers with try/catch or use express-async-errors to automatically catch rejected promises.