Conditional Express Middleware

raw JSON →
1.1.0 verified Thu Apr 23 auth: no javascript

condition-middleware is an Express.js middleware utility that enables conditional execution of other middleware functions based on a runtime predicate. It allows developers to define complex branching logic within their Express route definitions, executing different middleware stacks depending on a boolean, numeric, or string-based condition evaluated against the request object. This approach streamlines the creation of dynamic request processing flows, avoiding cumbersome `if/else` statements directly in route handlers. The package currently stands at version 1.1.0 and ships with TypeScript types, facilitating its use in modern JavaScript and TypeScript projects. While a formal release cadence isn't specified, its current version indicates active maintenance. Its key differentiator is simplifying the composition of conditional middleware, which is a common pattern for authentication, authorization, or feature toggling, compared to manual conditional chaining or other more complex conditional middleware solutions.

error TypeError: condition is not a function
cause Attempting to import the default ESM export using CommonJS `require` syntax, or incorrect named import.
fix
Use import condition from 'condition-middleware'; for ESM. If using CommonJS, ensure your build system correctly transpiles or configure module.exports = require('./dist/index').default; in a wrapper.
error Cannot read properties of undefined (reading 'role')
cause The condition function or a middleware inside the conditional block is attempting to access a property (e.g., `req.user.role`) that has not been initialized or is `undefined` on the `req` object.
fix
Ensure that any objects or properties accessed in your condition function (e.g., req.user) are properly initialized by preceding middlewares, or add null/undefined checks in your condition logic.
gotcha Error-handling middlewares are not directly accepted inside a condition middleware chain. Standard error handling should occur outside the `condition` block.
fix Place global or route-specific error-handling middleware after the `condition` block in the Express middleware chain.
gotcha When using the object-based condition syntax, if the value returned by your condition function does not match any key in the provided object, no middleware within the conditional block will be executed.
fix Ensure that your condition function's return values explicitly map to keys in the middleware object, or provide a default fallback mechanism in your logic.
npm install condition-middleware
yarn add condition-middleware
pnpm add condition-middleware

This quickstart demonstrates how to use `condition-middleware` to execute different Express middleware chains based on a dynamic boolean condition, such as a user's role extracted from request headers.

import express from 'express';
import condition from 'condition-middleware';

// Dummy middleware functions for demonstration
const initialMiddleware = (req, res, next) => { console.log('Initial'); req.user = { role: 'guest' }; next(); };
const validateRequestAdmin = (req, res, next) => { console.log('Validating admin request'); next(); };
const otherMiddlewareAdmin = (req, res, next) => { console.log('Admin specific logic'); next(); };
const validateRequestOthers = (req, res, next) => { console.log('Validating other request'); next(); };
const otherMiddlewares = (req, res, next) => { console.log('Common middleware after condition'); next(); };
const finalMiddleware = (req, res, next) => { console.log('Final middleware'); res.send('Done!'); };
const errorMiddleware = (err, req, res, next) => { console.error('Error:', err.message); res.status(500).send('Server Error'); };

const app = express();

// Condition function that returns a boolean
const isAdmin = (req) => {
    // Simulate different roles for demonstration
    const userRole = req.headers['x-user-role'] || 'guest';
    req.user.role = userRole;
    console.log(`User role: ${req.user.role}`);
    return req.user.role === 'admin';
};

app.get(
    '/',
    initialMiddleware,
    condition(isAdmin)(
        [validateRequestAdmin, otherMiddlewareAdmin], // true path
        [validateRequestOthers] // false path
    ),
    otherMiddlewares,
    finalMiddleware,
    errorMiddleware
);

app.listen(3000, () => {
    console.log('Server running on http://localhost:3000');
    console.log('Test with:');
    console.log('curl http://localhost:3000 -H "x-user-role: admin"');
    console.log('curl http://localhost:3000');
});