{"id":17422,"library":"co-compose","title":"Co Compose Middleware","description":"Co-compose is a lightweight, framework-agnostic middleware composition library for JavaScript and TypeScript applications, inspired by patterns found in Koa and AdonisJS. It enables developers to define an array of asynchronous functions (middleware) and execute them sequentially, with explicit control flow via a `next()` function. The current stable version is 7.0.3, which primarily includes dependency updates and minor fixes. Major versions, like v7, tend to update Node.js compatibility requirements, with minor and patch releases focusing on performance improvements and dependency hygiene. Key differentiators include its reported high performance (benchmarked against alternatives like `fastseries` and `middie`), flexibility with custom executors for different middleware shapes (e.g., ES6 classes), and a dedicated final handler mechanism. It ships with full TypeScript types, making it suitable for modern typed environments.","status":"active","version":"7.0.3","language":"javascript","source_language":"en","source_url":"https://github.com/poppinss/co-compose","tags":["javascript","adonisjs","koa","middleware","co","co-middleware","typescript"],"install":[{"cmd":"npm install co-compose","lang":"bash","label":"npm"},{"cmd":"yarn add co-compose","lang":"bash","label":"yarn"},{"cmd":"pnpm add co-compose","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The `Middleware` class is the primary export for creating and managing middleware chains. `co-compose` is primarily designed for ESM; while CJS imports might work, ESM is the recommended pattern.","wrong":"const { Middleware } = require('co-compose')","symbol":"Middleware","correct":"import { Middleware } from 'co-compose'"},{"note":"This type represents the signature for a standard middleware function: `(context: T, next: () => Promise<void>) => Promise<void> | void`.","symbol":"MiddlewareHandler","correct":"import type { MiddlewareHandler } from 'co-compose'"},{"note":"This type is used when defining custom middleware executors, allowing you to process non-standard middleware definitions (e.g., class instances).","symbol":"ExecutorFn","correct":"import type { ExecutorFn } from 'co-compose'"}],"quickstart":{"code":"import { Middleware } from 'co-compose'\n\nasync function fn1(next) {\n  console.log('executing fn1')\n  await next()\n}\n\nasync function fn2(next) {\n  console.log('executing fn2')\n  await next()\n}\n\n// Create a new middleware instance\nconst middleware = new Middleware()\n\n// Register middleware functions\nmiddleware.register([fn1, fn2])\n\n// Run the middleware chain with optional context\nasync function runChain() {\n  const ctx = { data: 'initial' }\n  await middleware.runner().run([ctx])\n  console.log('Middleware chain finished.')\n}\n\nrunChain().catch(console.error)\n","lang":"typescript","description":"Demonstrates basic middleware registration and sequential execution using the `Middleware` class, including how to pass context."},"warnings":[{"fix":"Upgrade your Node.js runtime to version 16 or later to maintain compatibility.","message":"Version 7.0.0 of `co-compose` dropped support for Node.js versions below 16. Projects upgrading to or using `co-compose@7.x.x` must ensure their environment runs Node.js 16 or newer.","severity":"breaking","affected_versions":">=7.0.0"},{"fix":"Always include `await next()` within your middleware functions, unless the intention is to terminate the chain and prevent further execution.","message":"Middleware functions must explicitly call `await next()` to transfer control to the subsequent middleware in the chain. Failing to call `next()` will prematurely halt the execution flow for any remaining middleware.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Carefully review your custom executor implementation to ensure it matches the expected interface and execution requirements of your custom middleware definitions.","message":"When implementing custom middleware executors, ensure the executor function correctly instantiates (if needed) and invokes the main method (e.g., `handle`) of your custom middleware object or class, passing all necessary parameters including the `next` function.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure your middleware function correctly accepts `next` as an argument (e.g., `async function (ctx, next) { ... }`) and that `next()` is called as `await next()`.","cause":"A middleware function attempted to call `next()` but `next` was either not passed as an argument or was not a function (e.g., due to an incorrect middleware signature or custom executor setup).","error":"TypeError: next is not a function"},{"fix":"Always declare your middleware functions with the `async` keyword when using `await`, for example: `async function myMiddleware(ctx, next) { await next(); }`.","cause":"The `await` keyword was used inside a middleware function that was not declared as `async`.","error":"SyntaxError: await is only valid in async functions and the top level bodies of modules"},{"fix":"Ensure `co-compose` is installed (`npm install co-compose` or `yarn add co-compose`) and that `Middleware` is imported using `import { Middleware } from 'co-compose'`.","cause":"The `Middleware` class was used without being correctly imported or after `co-compose` was not installed.","error":"ReferenceError: Middleware is not defined"}],"ecosystem":"npm","meta_description":null}