Full-stack-skills koa

Provides comprehensive guidance for Koa.js framework including middleware composition, context API, async/await patterns, and application structure. Use when the user asks about Koa, needs to create lightweight Node.js web applications, implement middleware, or build APIs with Koa.

install
source · Clone the upstream repo
git clone https://github.com/partme-ai/full-stack-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/partme-ai/full-stack-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/nodejs-skills/koa" ~/.claude/skills/partme-ai-full-stack-skills-koa && rm -rf "$T"
manifest: skills/nodejs-skills/koa/SKILL.md
source content

When to use this skill

Use this skill whenever the user wants to:

  • Build Node.js HTTP services with Koa and its onion-model middleware
  • Configure routing (koa-router), body parsing, error handling, and static files
  • Compose async middleware with
    ctx
    and
    next
    patterns
  • Create lightweight REST APIs or web applications

How to use this skill

Workflow

  1. Create app — instantiate Koa and add middleware in order
  2. Add routing — use
    @koa/router
    for route definitions
  3. Handle errors — add error middleware at the top of the stack
  4. Deploy — run behind reverse proxy with HTTPS

Quick Start Example

const Koa = require('koa');
const Router = require('@koa/router');
const bodyParser = require('koa-bodyparser');

const app = new Koa();
const router = new Router();

// Error handling middleware (top of stack)
app.use(async (ctx, next) => {
  try {
    await next();
  } catch (err) {
    ctx.status = err.status || 500;
    ctx.body = { error: err.message };
    ctx.app.emit('error', err, ctx);
  }
});

// Body parser
app.use(bodyParser());

// Routes
router.get('/api/items', async (ctx) => {
  const items = await Item.findAll();
  ctx.body = { items };
});

router.post('/api/items', async (ctx) => {
  const { name, price } = ctx.request.body;
  const item = await Item.create({ name, price });
  ctx.status = 201;
  ctx.body = item;
});

router.get('/api/items/:id', async (ctx) => {
  const item = await Item.findById(ctx.params.id);
  if (!item) {
    ctx.throw(404, 'Item not found');
  }
  ctx.body = item;
});

app.use(router.routes());
app.use(router.allowedMethods());

app.listen(3000, () => console.log('Server running on port 3000'));

Onion Model Middleware

// Logging middleware — demonstrates onion execution order
app.use(async (ctx, next) => {
  const start = Date.now();
  await next(); // <-- downstream
  const ms = Date.now() - start;
  ctx.set('X-Response-Time', `${ms}ms`);
  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});

Custom Middleware Example

// Authentication middleware
function requireAuth() {
  return async (ctx, next) => {
    const token = ctx.get('Authorization')?.replace('Bearer ', '');
    if (!token) {
      ctx.throw(401, 'Authentication required');
    }
    ctx.state.user = await verifyToken(token);
    await next();
  };
}

router.get('/api/profile', requireAuth(), async (ctx) => {
  ctx.body = ctx.state.user;
});

Best Practices

  • Use
    async/await
    correctly with
    next()
    — always
    await next()
    in middleware
  • Place error handling middleware at the top of the middleware stack
  • Use
    ctx.throw()
    for HTTP errors; listen to
    app.on('error')
    for logging
  • Deploy behind a reverse proxy (nginx) with HTTPS in production
  • Use
    @koa/cors
    for CORS configuration; keep middleware chain lean

Reference

Keywords

koa, Node.js, middleware, onion model, async/await, context, routing, REST API