Script Valley
Express.js: APIs and Middleware
Advanced Middleware PatternsLesson 5.5

How to structure Express middleware for large-scale applications

middleware folder structure, index.js barrel file, middleware ordering strategy, app-level vs router-level, conditional middleware, middleware composition, testing middleware

Structuring Middleware for Scale

As your app grows, middleware scattered across files becomes hard to manage. A clear structure makes every layer of your app easy to find and test.

Recommended folder structure

src/
  middleware/
    auth.js          # authenticate, authorize
    validate.js      # requireFields, validateSchema
    rateLimiter.js   # rateLimiter factory
    cache.js         # cacheMiddleware
    errorHandler.js  # AppError, errorHandler
    index.js         # barrel export
  routes/
    users.js
    products.js
  utils/
    asyncHandler.js
    response.js
  app.js

middleware/index.js โ€” barrel file

module.exports = {
  authenticate: require('./auth').authenticate,
  authorize: require('./auth').authorize,
  requireFields: require('./validate').requireFields,
  rateLimiter: require('./rateLimiter'),
  cacheMiddleware: require('./cache'),
  errorHandler: require('./errorHandler')
};

app.js โ€” clean and readable

const express = require('express');
const { errorHandler, rateLimiter } = require('./middleware');
const usersRouter = require('./routes/users');

const app = express();
app.use(express.json());
app.use(rateLimiter(100, 60000));
app.use('/api/users', usersRouter);
app.use(errorHandler);

module.exports = app;

Export app from app.js and start the server in a separate server.js. This separation makes testing easier โ€” you can import app in tests without starting the HTTP server.

How to structure Express middleware for large-scale applications โ€” Advanced Middleware Patterns โ€” Express.js: APIs and Middleware โ€” Script Valley โ€” Script Valley