Registry / aws / serverless-compose

serverless-compose

JSON →
library2.4.0jsnpmunverified

serverless-compose is a lightweight, functional middleware framework specifically designed for AWS Lambda functions, enabling the creation of composable, "onion-style" middleware stacks. Currently at version 2.4.0, its release cadence is not explicitly stated in the provided documentation, but it appears actively maintained. A key differentiator is its zero-dependency philosophy, ensuring a minimal bundle size and avoiding dependency conflicts. Unlike more opinionated frameworks, serverless-compose focuses on providing a thin `compose` function and flexible patterns like `recoveryMiddleware` and `timingLogMiddleware` without enforcing specific architectural designs, allowing developers to define their middleware stack with explicit, functional wrappers around their Lambda handlers. It aims to prevent the "fossilization" of bad middleware habits by promoting a clear, functional approach for event processing.

npm install serverless-compose
INSTALL
IMPORT
SIG · SERVERLESS-COMPOSE
S
serverless-compose
awsjavascriptv2.4.0
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

compose
import { compose } from 'serverless-compose'
const { compose } = require('serverless-compose')
The library primarily uses ES Modules (ESM). Using `require` will result in a runtime error in ESM-only environments.
recoveryMiddleware
import { recoveryMiddleware } from 'serverless-compose'
const recoveryMiddleware = require('serverless-compose').recoveryMiddleware
Prefer named ESM imports. Direct CommonJS `require` might fail if your Lambda environment is configured for ESM or if transpilation doesn't handle it correctly.
timingLogMiddleware
import { timingLogMiddleware } from 'serverless-compose'
import timingLogMiddleware from 'serverless-compose/timingLogMiddleware'
All core utilities are named exports from the main package entry point, not default exports or sub-path imports.

Demonstrates basic setup with `compose`, `timingLogMiddleware` for logging duration, and `recoveryMiddleware` for graceful error handling in an AWS Lambda handler.

import { compose, recoveryMiddleware, timingLogMiddleware } from 'serverless-compose'; // Suppose this is a client that fetches the weather from some external API class WeatherClient { static async askBadAPIForWeather() { // Simulate a failing API call 50% of the time if (Math.random() > 0.5) { throw new Error('Weather API is down!'); } return { temperature: 25, unit: 'C' }; } } // Your actual handler code async function getWeather(request, context) { const response = await WeatherClient.askBadAPIForWeather(); return { statusCode: 200, body: JSON.stringify(response), }; } // Your own custom logging function async function logDuration(duration) { console.log(`It took: ${duration}ms to return the weather`); } // Your own custom error handler async function sendError(error) { console.error('Handler Error:', error); return { statusCode: 500, body: JSON.stringify({ error: `${error.message}`, message: 'The darn weather API failed me again!', }), }; } const TimingMiddleware = timingLogMiddleware(logDuration); const RecoveryMiddleware = recoveryMiddleware(sendError); const MyMiddlewareStack = compose( TimingMiddleware, RecoveryMiddleware, ); export const lambdaHandler = MyMiddlewareStack(getWeather);
Debug
Known issues
gotchaMiddleware order is crucial in `serverless-compose`'s onion-style architecture. Middleware functions are applied from right to left (outermost to innermost) in the `compose` function, but execute in an 'onion' fashion (outer wraps inner). Misordering can lead to unexpected behavior or missed error handling.
fix
Carefully consider the execution flow. Middleware like `recoveryMiddleware` that needs to catch errors from subsequent middleware or the handler should typically be placed earlier in the `compose` argument list (further to the right), allowing it to wrap and protect the functions composed after it.
affects: >=1.0.0
gotchaWhen migrating older CommonJS (CJS) Lambda functions or integrating CJS dependencies, you might encounter issues with `serverless-compose` as it primarily uses ES Modules (ESM). AWS Lambda environments need proper configuration (`"type": "module"` in `package.json` or `.mjs` file extensions) to handle ESM correctly.
fix
Ensure your project's `package.json` specifies `"type": "module"` for ESM, or use a build step (e.g., esbuild, webpack) to transpile your code to CJS if your environment strictly requires it. For hybrid setups, consider using dynamic `import()` within CJS modules to load ESM dependencies.
affects: >=1.0.0
gotchaUnhandled promise rejections or uncaught exceptions within your Lambda handler or custom middleware can lead to generic `502 Internal Server Error` responses from API Gateway without informative bodies. `recoveryMiddleware` is designed to mitigate this, but must be configured correctly.
fix
Always include and configure `recoveryMiddleware` (or similar custom error handling) as one of the outermost middleware in your `compose` stack. Ensure its error handling function returns a valid API Gateway proxy response object (e.g., `{ statusCode: 500, body: JSON.stringify({ message: 'Error' }) }`).
affects: >=1.0.0
gotchaWhile the library itself is functional, complex Serverless Framework deployments using shared source directories or monorepos can suffer from path resolution and bundling issues, especially when coupled with plugins like `serverless-esbuild` or `serverless-plugin-typescript`.
fix
Verify `handler` paths in `serverless.yml` are correct relative to the service's `package.json`. For monorepos, ensure your build process correctly copies or symlinks shared code, or configure bundling plugins to resolve modules from the root. Explicitly setting `srcDir` might be needed for some bundlers.
affects: >=1.0.0
Errors
Common errors & fixes
SyntaxError: Cannot use import statement outside a module
Your Node.js environment or AWS Lambda configuration is treating your code as CommonJS (CJS) but it uses ESM `import` statements.
fix
Add `"type": "module"` to your `package.json`, or rename your file to `.mjs`, or ensure your build process (e.g., Babel, TypeScript compiler, bundler) transpiles ESM to CJS if your environment is CJS-only.
ReferenceError: require is not defined in ES module scope, you can use import instead
Your Node.js environment or AWS Lambda configuration is treating your code as an ES Module (ESM), but you are attempting to use the CommonJS `require` function.
fix
Replace all `require()` calls with `import` statements for `serverless-compose` and other dependencies. If you need to load CJS modules from an ESM context, use `await import('your-cjs-module')`.
502 Internal Server Error (from API Gateway) with errorMessage: "Unhandled Promise Rejection" in CloudWatch logs
Your Lambda handler or a middleware function threw an error or returned a rejected promise, and no subsequent middleware (like `recoveryMiddleware`) transformed it into a valid API Gateway response.
fix
Ensure `recoveryMiddleware` is included in your `compose` stack and its error handling function is correctly implemented to return a structured API Gateway proxy response object (e.g., `{ statusCode: 500, body: JSON.stringify({ message: 'Error' }) }`). Place `recoveryMiddleware` towards the 'right' in your `compose` arguments to wrap all preceding middleware and your handler.
Upgrade
Version history
2.4.0latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
13 hits · last 30 days
node
12
Resources
serverless-compose — npm install serverless-compose · libregistry