koa-compose
raw JSON → 4.1.0 verified Sat Apr 25 auth: no javascript
Utility to compose Koa middleware functions into a single middleware. Current stable version is 4.1.0. Low release cadence; maintained as part of the Koa ecosystem. Key differentiator: it is the canonical middleware composition function for Koa, supporting async/await and error handling through promises. Alternatives like `koa-convert` or custom loops exist, but this is minimal and standard.
Common errors
error TypeError: middleware is not a function ↓
cause Passing non-array or undefined to compose.
fix
Ensure compose is called with an array: compose([func1, func2])
error Error: next() called multiple times ↓
cause Calling next() more than once in a middleware function.
fix
Ensure each middleware calls next() exactly once, or handle conditional logic properly.
error ReferenceError: compose is not defined ↓
cause Missing import or using incorrect import syntax.
fix
Use proper import: import compose from 'koa-compose' or const compose = require('koa-compose')
Warnings
gotcha compose expects an array of middleware; passing non-array will throw. ↓
fix Always wrap middleware in an array: compose([mw1, mw2])
gotcha Middleware must be async functions returning Promises; otherwise compose may not work correctly. ↓
fix Define middleware as async (ctx, next) => { await next(); }
gotcha compose returns a single middleware function; cannot be used directly as router-level middleware without wrapping. ↓
fix Use the returned function with app.use() or router middleware stack.
Install
npm install koa-compose yarn add koa-compose pnpm add koa-compose Imports
- compose wrong
const compose = require('koa-compose')correctimport compose from 'koa-compose' - compose wrong
const { compose } = require('koa-compose')correctconst compose = require('koa-compose') - compose wrong
import { compose } from 'koa-compose'correctimport compose from 'koa-compose'
Quickstart
import Koa from 'koa';
import compose from 'koa-compose';
const app = new Koa();
const logger = async (ctx, next) => {
console.log(`${ctx.method} ${ctx.url}`);
await next();
};
const responseTime = async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
ctx.set('X-Response-Time', `${ms}ms`);
};
const composed = compose([logger, responseTime]);
app.use(composed);
app.listen(3000);
console.log('Server running on port 3000');