Mounting Sub-Apps

koa-mount Scopes a Middleware or Sub-App to a URL Prefix

Mounting Sub-Apps

koa-mount lets you attach a middleware or a full Koa sub-application at a specific path prefix, isolating it from the parent app and keeping large codebases modular.

3 min read Level 2/5 #koa#middleware#mount
What you'll learn
  • Mount a Koa sub-application under a path prefix with koa-mount
  • Explain how ctx.path is rewritten inside a mounted app
  • Compare koa-mount with @koa/router's prefix option

koa-mount wraps a middleware or a full Koa application and makes it respond only when ctx.path starts with a given prefix. Inside the mounted app, ctx.path is rewritten to strip the prefix — so the sub-app does not need to know where it is mounted.

Installation

npm install koa-mount

Mounting a Single Middleware

import Koa from 'koa';
import mount from 'koa-mount';
import serve from 'koa-static';

const app = new Koa();

// Serve ./public only for requests to /static/*
app.use(mount('/static', serve('./public')));

app.listen(3000);

A request to /static/logo.png reaches koa-static with ctx.path rewritten to /logo.png.

Mounting a Sub-Application

Each sub-app is a fully independent Koa instance with its own middleware stack:

import Koa from 'koa';
import mount from 'koa-mount';
import Router from '@koa/router';

// --- v1 sub-app ---
const v1 = new Koa();
const v1Router = new Router();
v1Router.get('/users', (ctx) => { ctx.body = { version: 1 }; });
v1.use(v1Router.routes());

// --- v2 sub-app ---
const v2 = new Koa();
const v2Router = new Router();
v2Router.get('/users', (ctx) => { ctx.body = { version: 2 }; });
v2.use(v2Router.routes());

// --- parent app ---
const app = new Koa();
app.use(mount('/v1', v1));
app.use(mount('/v2', v2));
app.listen(3000);

GET /v1/users hits v1; GET /v2/users hits v2. Each sub-app sees ctx.path as /users.

ctx.path Rewriting

This is the key difference between koa-mount and a router prefix:

Toolctx.path insideURL prefix stripped?
koa-mount('/api', ...)/users (prefix removed)Yes
router.prefix('/api')/api/users (prefix kept)No

When to Use Each

Use koa-mount when:

  • You are composing independent Koa apps (e.g., micro-frontends, versioned APIs).
  • A middleware is path-scoped by convention (e.g., koa-static).

Use @koa/router prefix when:

  • You want all routes in one app but grouped under a prefix.
  • You need route params from the prefix (e.g., /api/:version/users).

Shared Middleware on the Parent

Middleware registered on the parent app runs before the mounted app’s own middleware. Mount the error handler on the parent to catch errors in all sub-apps:

app.use(errorHandler); // wraps all mounted sub-apps
app.use(mount('/v1', v1));
app.use(mount('/v2', v2));

Up Next

The final lesson in this chapter brings together practical patterns you will use daily: request IDs, response timing, conditional auth, and decorating ctx.state.

Practical Middleware Patterns →