Files
khoa/Readme.md
Khoajs Sync Bot 2f16d196c0
Some checks failed
Node.js CI / build (18.x) (push) Has been cancelled
Node.js CI / build (20.x) (push) Has been cancelled
Node.js CI / build (22.x) (push) Has been cancelled
chore: apply Khoajs naming transformations (upstream sync)
2026-04-17 20:57:37 +00:00

16 KiB

Khoa middleware framework for nodejs

gitter NPM version [![build status][github-action-image]][github-action-url] Test coverage OpenCollective Backers OpenCollective Sponsors [![PR's Welcome][pr-welcoming-image]][pr-welcoming-url]

Expressive HTTP middleware framework for node.js to make web applications and APIs more enjoyable to write. Khoa's middleware stack flows in a stack-like manner, allowing you to perform actions downstream then filter and manipulate the response upstream.

Why Khoajs?

Khoajs is a friendly and transparent fork of Koa, created as a fun project and tribute to Khoa Nguyen Hai. It keeps upstream behavior while applying naming changes and automated sync maintenance.

Installation

Khoa requires node v18.0.0 or higher for ES2015 and async function support.

npm install khoajs

Hello Khoa

const Khoa = require('khoajs');
const app = new Khoa();

app.use(ctx => {
  ctx.body = 'Hello Khoa';
});

app.listen(3000);

Getting started

  • Guide - Go straight to the docs.

Middleware

Khoa is a middleware framework that can take two different kinds of functions as middleware:

  • async function
  • common function

Here is an example of logger middleware with each of the different functions:

async functions (node v7.6+)

app.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});

Common function

// Middleware normally takes two parameters (ctx, next), ctx is the context for one request,
// next is a function that is invoked to execute the downstream middleware. It returns a Promise with a then function for running code after completion.

app.use((ctx, next) => {
  const start = Date.now();
  return next().then(() => {
    const ms = Date.now() - start;
    console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
  });
});

Khoa v1.x Middleware Signature

The middleware signature changed between v1.x and v2.x. The older signature is deprecated.

Old signature middleware support has been removed in v3

Please see the Migration Guide from v2.x to v3.x for information on upgrading from v2.x to v3.x, and the Migration Guide from v1.x to v2.x for information on upgrading from v1.x to v2.x.

Context, Request and Response

Each middleware receives a Khoa Context object that encapsulates an incoming http message and the corresponding response to that message. ctx is often used as the parameter name for the context object.

app.use(async (ctx, next) => { await next(); });

Khoa provides a Request object as the request property of the Context. Khoa's Request object provides helpful methods for working with http requests which delegate to an IncomingMessage from the node http module.

Here is an example of checking that a requesting client supports xml.

app.use(async (ctx, next) => {
  ctx.assert(ctx.request.accepts('xml'), 406);
  // equivalent to:
  // if (!ctx.request.accepts('xml')) ctx.throw(406);
  await next();
});

Khoa provides a Response object as the response property of the Context. Khoa's Response object provides helpful methods for working with http responses which delegate to a ServerResponse .

Khoa's pattern of delegating to Node's request and response objects rather than extending them provides a cleaner interface and reduces conflicts between different middleware and with Node itself as well as providing better support for stream handling. The IncomingMessage can still be directly accessed as the req property on the Context and ServerResponse can be directly accessed as the res property on the Context.

Here is an example using Khoa's Response object to stream a file as the response body.

app.use(async (ctx, next) => {
  await next();
  ctx.response.type = 'xml';
  ctx.response.body = fs.createReadStream('really_large.xml');
});

The Context object also provides shortcuts for methods on its request and response. In the prior examples, ctx.type can be used instead of ctx.response.type and ctx.accepts can be used instead of ctx.request.accepts.

For more information on Request, Response and Context, see the Request API Reference, Response API Reference and Context API Reference.

Khoa Application

The object created when executing new Khoa() is known as the Khoa application object.

The application object is Khoa's interface with node's http server and handles the registration of middleware, dispatching to the middleware from http, default error handling, as well as configuration of the context, request and response objects.

Learn more about the application object in the Application API Reference.

Documentation

Troubleshooting

Check the Troubleshooting Guide or Debugging Khoa in the general Koa guide.

Running tests

$ npm test

Reporting vulnerabilities

To report a security vulnerability, please do not open an issue, as this notifies attackers of the vulnerability. Instead, please email dead_horse, jonathanong, and niftylettuce to disclose.

Source Code

Authors

See AUTHORS.

Community

Backers

Support us with a monthly donation and help us continue our activities.

Sponsors

Become a sponsor and get your logo on our README on Github with a link to your site.

License