Modern autorouter middleware for Koa.js v2+ with async/await support, based on folder/file hierarchy.
- π Modern: Full async/await support for Koa v2+
- π File-based routing: Routes automatically generated from directory structure
- π― Convention over configuration: Minimal setup, maximum productivity
- π§ Flexible: Works with any template engine
- π¦ TypeScript support: Full type definitions included
- π‘οΈ Secure: Updated dependencies with security patches
v1.x (Generator functions):
exports.index = function *(next) {
this.state.name = 'Server';
yield this.view();
};v2.x (Async/await):
exports.index = async function(ctx, next) {
ctx.state.name = 'Modern Server';
await ctx.view();
};npm install koa-autorouterapp.js
const Koa = require('koa');
const path = require('path');
const views = require('koa-views');
const autorouter = require('koa-autorouter');
const app = new Koa();
// Setup template engine (example with Handlebars)
app.use(views(path.join(__dirname, 'views'), {
extension: 'html',
map: { html: 'handlebars' }
}));
// Setup autorouter
app.use(autorouter({
root: path.join(__dirname, 'views/'),
ext: '.html'
}));
app.listen(3000);views/
βββ index.js # GET /
βββ index.html # Template for /
βββ user/
β βββ profile.js # GET /user/profile
β βββ profile.html # Template
β βββ settings.js # GET /user/settings
βββ admin/
β βββ index.js # GET /admin/
β βββ help.html # GET /admin/help (standalone view)
β βββ reports/
β βββ daily.js # GET /admin/reports/daily
// views/user/index.js
exports.index = async function(ctx, next) {
ctx.state.users = await getUsers();
await ctx.view(); // Renders user/index.html
};// views/posts/index.js
// Optional middleware for all actions
exports.middleware = async function(ctx, next) {
ctx.state.currentUser = await getCurrentUser(ctx);
await next();
};
// GET /posts
exports.index = async function(ctx) {
ctx.state.posts = await Post.findAll();
await ctx.view();
};
// POST /posts
exports.create = async function(ctx) {
const post = await Post.create(ctx.request.body);
ctx.redirect(`/posts/${post.id}`);
};
// GET /posts/:id
exports.select = async function(ctx) {
const id = ctx.state.id; // Auto-populated from URL
ctx.state.post = await Post.findById(id);
await ctx.view();
};
// POST /posts/:id
exports.update = async function(ctx) {
const id = ctx.state.id;
await Post.update(id, ctx.request.body);
ctx.redirect(`/posts/${id}`);
};
// GET /posts/:id/edit
exports.edit = async function(ctx) {
const id = ctx.state.id;
ctx.state.post = await Post.findById(id);
await ctx.view();
};
// POST /posts/:id/edit
exports.save = async function(ctx) {
const id = ctx.state.id;
await Post.update(id, ctx.request.body);
ctx.redirect(`/posts/${id}`);
};
// GET /posts/:id/delete
exports.delete = async function(ctx) {
const id = ctx.state.id;
await Post.delete(id);
ctx.redirect('/posts');
};app.use(autorouter({
root: path.join(__dirname, 'views/'), // Controllers directory
ext: '.html', // Template extension
enableStandalone: true // Enable views without controllers
}));const views = require('koa-views');
app.use(views('views', { extension: 'hbs', map: { hbs: 'handlebars' } }));const views = require('koa-views');
app.use(views('views', { extension: 'pug' }));const views = require('koa-views');
app.use(views('views', { extension: 'ejs' }));| File Path | URL | HTTP Method |
|---|---|---|
views/index.js β exports.index |
GET / |
GET |
views/user/profile.js β exports.index |
GET /user/profile |
GET |
views/posts/index.js β exports.create |
POST /posts |
POST |
views/posts/index.js β exports.select |
GET /posts/:id |
GET |
views/admin/help.html |
GET /admin/help |
GET (standalone) |
Run the example:
cd example
npm install
npm startVisit:
- http://localhost:3000/ β
views/index.js - http://localhost:3000/admin β
views/admin/index.js - http://localhost:3000/admin/help β
views/admin/help.html(standalone) - http://localhost:3000/reports/help β
views/reports/help.js
import autorouter from 'koa-autorouter';
import { Context } from 'koa';
// Controller with types
export const index = async (ctx: Context) => {
ctx.state.message = 'Hello TypeScript!';
await ctx.view();
};| Feature | koa-autorouter v2 | Next.js | Nuxt.js |
|---|---|---|---|
| Framework | Koa.js | React | Vue.js |
| File-based routing | β | β | β |
| Server-side only | β | β | β |
| Lightweight | β | β | β |
| Template agnostic | β | β | β |
- Koa version: Requires Koa v2+ (Node.js 14+)
- Function signatures:
function*(ctx, next)βasync function(ctx, next) - Context:
thisβctxparameter - Async:
yieldβawait - Dependencies: Removed lodash, co-fs dependencies
MIT
- Fork the repository
- Create your feature branch
- Add tests for new features
- Ensure all tests pass
- Submit a pull request
Upgrade your Koa routing to the modern era! π