{"id":17087,"library":"compose-middleware","title":"Compose Middleware","description":"compose-middleware is a utility library designed to combine an array of Express- or Connect-style middleware functions into a single, cohesive middleware function. This package is currently stable at version 5.0.1, with recent updates primarily focusing on TypeScript type improvements and stricter function signatures. Historically, major versions have introduced changes to error handling logic and middleware validation. Its key differentiators include built-in support for inline error handling middleware, which can be composed separately using the `errors` export, and robust validation of middleware functions to prevent common pitfalls in middleware chains. It provides a flexible way to structure complex middleware pipelines for web frameworks.","status":"active","version":"5.0.1","language":"javascript","source_language":"en","source_url":"git://github.com/blakeembrey/compose-middleware","tags":["javascript","middleware","express","compose","flatten","function","typescript"],"install":[{"cmd":"npm install compose-middleware","lang":"bash","label":"npm"},{"cmd":"yarn add compose-middleware","lang":"bash","label":"yarn"},{"cmd":"pnpm add compose-middleware","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Used for internal debugging, updated to v3 in compose-middleware v4.0.0.","package":"debug","optional":false}],"imports":[{"note":"The `compose` function is a named export for ESM. For CommonJS, it's accessed as a property of the default require.","wrong":"const compose = require('compose-middleware').compose","symbol":"compose","correct":"import { compose } from 'compose-middleware'"},{"note":"The `errors` function is a named export specifically for composing 4-argument error middleware. Similar CommonJS usage as `compose`.","wrong":"const errors = require('compose-middleware').errors","symbol":"errors","correct":"import { errors } from 'compose-middleware'"},{"note":"Type import for the main middleware composition function signature, useful for strict TypeScript environments.","symbol":"ComposeMiddleware","correct":"import type { ComposeMiddleware } from 'compose-middleware'"}],"quickstart":{"code":"import express from 'express';\nimport { compose, errors } from 'compose-middleware';\n\nconst app = express();\n\n// A basic middleware function\nconst logRequest = (req: express.Request, res: express.Response, next: express.NextFunction) => {\n  console.log(`Request received: ${req.method} ${req.url}`);\n  next();\n};\n\n// An error-handling middleware\nconst handleError = (err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => {\n  console.error(`An error occurred: ${err.message}`);\n  res.status(500).send('Something broke!');\n};\n\n// Composing a sequence of regular middleware\napp.use(compose([\n  logRequest,\n  (req, res, next) => { req.body = req.body || {}; next(); },\n  (req, res, next) => { console.log('Processing request...'); next(); }\n]));\n\n// Composing a sequence of error-handling middleware\napp.use(errors([\n  (err, req, res, next) => { if (err.message === 'validation error') { console.log('Validation failed'); return next(err); } next(err); },\n  handleError\n]));\n\n// Example route to trigger middleware\napp.get('/', (req, res) => {\n  res.send('Hello World!');\n});\n\n// Example route to trigger an error\napp.get('/error', (req, res, next) => {\n  next(new Error('This is an intentional error!'));\n});\n\nconst PORT = process.env.PORT || 3000;\napp.listen(PORT, () => {\n  console.log(`Server running on http://localhost:${PORT}`);\n});","lang":"typescript","description":"This example demonstrates composing both standard middleware and error-handling middleware for an Express application using `compose` and `errors` exports. It sets up an Express server with logging, body parsing, and a global error handler, showing how different middleware types are integrated into the application's request processing pipeline."},"warnings":[{"fix":"Review and update middleware function signatures to match the stricter `(req, res, next)` or `(err, req, res, next)` patterns, ensuring all parameters are explicitly handled.","message":"Version 5.0.0 introduced stricter TypeScript type signatures, removing optional types from function parameters. This may cause type errors in existing TypeScript projects.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Thoroughly test existing error handling middleware after upgrading. Ensure custom error handling logic correctly catches and processes errors without unintended re-throws or missed errors.","message":"Version 3.0.0 changed the error re-throwing mechanism. Errors thrown synchronously from `done()` or other inconsistent states are now re-thrown higher up the stack, which might alter error handling flow for complex or edge-case error patterns.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Inspect middleware functions to ensure `next()` is only called once per request. If multiple asynchronous operations are involved, use promises or async/await to ensure `next()` is only invoked after all operations complete, or handle branching logic explicitly.","message":"Version 2.2.0 introduced validation that throws an error if `next()` is called multiple times within a single middleware execution. This prevents common pitfalls and ensures predictable middleware execution.","severity":"breaking","affected_versions":">=2.2.0"},{"fix":"Ensure all entries in the middleware array are valid functions. Error handlers must accept exactly four arguments `(err, req, res, next)`, while regular middleware accepts three `(req, res, next)`.","message":"Version 2.0.0 added validation for all middleware functions and introduced support for 4-argument error handlers. Providing non-function middleware or incorrectly structured error handlers will now result in errors.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Always use `compose` for regular middleware chains and `errors` for chains specifically designed to handle errors. Do not mix their intended uses as their signatures differ.","message":"The `compose` function returns a 3-argument middleware function (req, res, next), suitable for regular request processing. The `errors` function returns a 4-argument error middleware function (err, req, res, next).","severity":"gotcha","affected_versions":">=2.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Review the middleware where the error originates and ensure `next()` is called exactly once. Use `return next();` to prevent accidental subsequent execution or wrap asynchronous calls in promises.","cause":"A middleware function within the composed chain called `next()` more than once for a single request, which is disallowed since v2.2.0.","error":"Error: next() called multiple times"},{"fix":"Explicitly define types for `req`, `res`, `next`, and `err` (if applicable) in your middleware functions. Ensure 3-argument middleware is used with `compose` and 4-argument middleware with `errors`, aligning with the library's expected types.","cause":"This TypeScript error indicates a mismatch in middleware function signatures, often due to the stricter type definitions introduced in v5.0.0, or incorrect argument counts (e.g., passing a 4-arg function where a 3-arg is expected).","error":"Argument of type '(...)' is not assignable to parameter of type '(...)'"},{"fix":"Verify that all items in the array passed to `compose` or `errors` are indeed functions, and not `null`, `undefined`, or other data types.","cause":"An element passed into the array for `compose` or `errors` was not a JavaScript function. This validation was added in v2.0.0.","error":"Error: Middleware must be a function"}],"ecosystem":"npm","meta_description":null}