@koa/multer

Koa middleware that adapts Express's multer into promise-based handlers for parsing multipart/form-data uploads.

Library
npm
v4.0.0
174stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
37/100Needs Attention
Development Activity0
Maintenance20
Community48
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
65/100Good
Architecture68
Code Quality75
Innovation72
Learning Curve45

@koa/multer is the official koajs-organization fork of the community’s koa-multer package, giving Koa applications a drop-in way to handle multipart/form-data file uploads using the same multer engine that powers Express apps. Rather than reimplementing multipart parsing, it wraps multer’s callback-based API in a thin promisifying layer so .single(), .array(), .fields(), .none(), and .any() all become Koa-friendly async middleware, with uploaded files and fields copied onto both ctx and ctx.request for convenience.

Because it depends on koa and multer as peer dependencies rather than bundling either, teams control exactly which multer version (and therefore which storage engines and Express-side ecosystem) they’re running underneath, while getting a maintained integration layer instead of hand-rolling one themselves.

What You Get

  • Promise-wrapped single, array, fields, none, and any upload handlers matching multer’s own API
  • Automatic copying of parsed body, file, and files onto both ctx and ctx.request
  • Passthrough access to multer’s diskStorage and memoryStorage engines
  • Full compatibility with any multer 1.x or 2.x storage engine or file filter your app already uses

Common Use Cases

  • Accepting avatar or profile-photo uploads in a Koa-based REST API
  • Handling multi-file form submissions (e.g. document attachments) with @koa/router
  • Migrating an existing Express + multer upload flow to a Koa application
  • Building admin/back-office forms that need in-memory or on-disk temporary file storage before processing

Under The Hood

Architecture @koa/multer is a single-file adapter (index.js) that wraps the callback-based Express-style multer library and adapts each of its methods (any, array, fields, none, single) into Koa-compatible async middleware by promisifying multer’s (req, res, callback) signature and copying req.body/req.file/req.files onto Koa’s ctx.request and ctx before calling next(). There is no internal layering beyond this thin translation layer — multer itself (a peer dependency) does all the actual multipart parsing, storage engine selection, and validation, so the module’s only responsibility is bridging Node’s raw req/res objects into Koa’s context and callback style into promises/async-await.

Tech Stack The package is plain, untranspiled JavaScript (CommonJS, require/module.exports) with no build step — the published package ships only LICENSE, README.md, and index.js. It declares multer and koa as peer dependencies rather than direct dependencies, letting consumers pick their own compatible major versions of each; devDependencies cover only tooling — Mocha for tests, nyc for coverage, xo (an ESLint preset) plus Prettier for linting/formatting, Husky and commitlint for enforcing Conventional Commits, and @koa/router/form-data/concat-stream as test-only harness dependencies.

Code Quality Testing is unusually thorough for the package’s size: a dozen-plus Mocha test files cover disk/memory storage, field selection, file ordering, Unicode filenames, error handling, koa-integration, and a regression test for a specific numbered issue, run via mocha —exit and measured with nyc coverage in CI. GitHub Actions runs the suite across Node 18/20/22 on every push. Linting is enforced through xo with Prettier formatting rules embedded in package.json, and Husky’s pre-commit hook re-runs the full test/lint suite locally. The codebase has no TypeScript types or .d.ts declarations, so consumers get no compile-time safety — a real gap for an otherwise well-tested package.

API Design The public API deliberately mirrors multer’s own: calling multer(options) returns an object with the same .single(), .array(), .fields(), .none(), and .any() methods, plus passthrough diskStorage/memoryStorage helpers, so anyone already familiar with Express’s multer can adopt this Koa build with zero relearning. Boilerplate is minimal — a route just chains the returned middleware into @koa/router, and uploaded data lands predictably on both ctx.file/ctx.files and ctx.request.file/ctx.request.files. The tradeoff is that the module inherits multer’s entire callback-oriented, non-Koa-idiomatic options surface as-is, rather than offering a redesigned, more Koa-native configuration API.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search