How does the middleware composition work?
How does the middleware composition work?
About koajs/koa · 2 messages · last activity 7/12/2026
Koa's middleware composition follows a stack-like execution model where middleware functions are executed in order going down, then in reverse order coming back up.
How It Works
When you add middleware using app.use(fn) [lib/application.js:L149], the middleware functions are stored in an array [lib/application.js:L154]. When a request arrives, callback() [lib/application.js:L166] composes all middleware using this.compose(this.middleware) [lib/application.js:L165] and passes the composed function to handleRequest() [lib/application.js:L195].
Execution Flow
Middleware execution follows a nested pattern. Here's a concrete example from the tests [tests/application/use.test.js:L8-L35]:
app.use((ctx, next) => {
calls.push(1) // executes first, going down
return next().then(() => {
calls.push(6) // executes last, coming back up
})
})
app.use((ctx, next) => {
calls.push(2) // executes second
return next().then(() => {
calls.push(5) // executes second to last
})
})
app.use((ctx, next) => {
calls.push(3) // executes third (deepest)
return next().then(() => {
calls.push(4) // executes fourth (coming back)
})
})
Result: [1, 2, 3, 4, 5, 6]
Supported Middleware Patterns
Koa supports two middleware styles that can be mixed:
- Async functions - using
await next()[README.md:L50-L57] - Common functions - using
return next().then(...)[README.md:L65-L79]
Both styles work together seamlessly, as shown in [tests/application/use.test.js:L36-L75].
The key mechanism is that next is a function that returns a Promise, allowing middleware to execute downstream logic and then handle the response on the way back up.
FOLLOW_UPS:
- What is the compose function implementation?
- How does error handling work in middleware?
- Can you customize the composition function?
Want to ask your own question?
Open chat for koajs/koaPublic Q&A. Generated by RepoPilot from the actual source of koajs/koa. AI answers can be incomplete or stale — verify before relying on them.