Registry / web-framework / app-builder

app-builder

JSON →
library7.0.4jsnpmunverified

app-builder is a JavaScript library for creating robust and composable asynchronous middleware pipelines, following the 'onion' model commonly seen in frameworks like Koa. It leverages Promises to enable clear and sequential execution of middleware functions, each capable of performing operations before and after subsequent middleware in the stack. The current stable version is 7.0.4. While a specific release cadence isn't explicitly stated, the active GitHub repository suggests ongoing maintenance. Its key differentiator lies in its simplicity and functional approach to middleware composition, providing a lightweight alternative to larger frameworks for building request-response flows or general data processing pipelines. It ships with TypeScript types, ensuring a better developer experience in TypeScript projects.

web-frameworkhttp-networking
npm install app-builder
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 'app-builder'
const { compose } = require('app-builder')
The library primarily uses ES Modules. While CommonJS might work in some setups, ESM is the recommended and modern way to import.

Demonstrates how to compose asynchronous middleware functions into a pipeline, including logging, core logic, and robust error handling, showcasing both successful and failing scenarios.

import { compose } from 'app-builder'; // Define a simple logger middleware that logs entry and exit const loggerMiddleware = async (ctx, next) => { console.log(`Entering middleware: ${ctx.name}`); await next(); // This is crucial to pass control to the next middleware console.log(`Exiting middleware: ${ctx.name}`); }; // Define a core logic middleware that modifies the context const coreLogicMiddleware = async (ctx, next) => { ctx.data = 'Processed data'; console.log(`Core logic executed, data: ${ctx.data}`); await next(); }; // Define an error handling middleware to gracefully catch exceptions const errorHandlingMiddleware = async (ctx, next) => { try { await next(); } catch (error) { console.error(`An error occurred: ${error.message}`); ctx.error = error.message; // Store error in context } }; // Compose the middleware pipeline const app = compose( loggerMiddleware, // First, logs entry errorHandlingMiddleware, // Catches errors from subsequent middleware coreLogicMiddleware, // Performs core data processing async (ctx, next) => { // This is an inline middleware demonstrating further processing ctx.status = 'completed'; console.log(`Final status set to: ${ctx.status}`); await next(); // Even if it's the last, always call next() } ); // Define an initial context object const initialContext = { name: 'MyPipeline', data: null, status: null, error: null }; // Execute the pipeline app(initialContext) .then(() => { console.log('Pipeline finished. Final context:', initialContext); }) .catch(err => { console.error('Unhandled pipeline error (should not happen with errorHandlingMiddleware):', err); }); // Example with an intentional error to show error handling const failingApp = compose( errorHandlingMiddleware, // This will catch the error async (ctx, next) => { console.log('Failing middleware attempting to run...'); throw new Error('Something went wrong in the pipeline!'); } ); const failingContext = { name: 'FailingPipeline', error: null }; failingApp(failingContext) .then(() => { console.log('Failing pipeline finished. Final context:', failingContext); }) .catch(err => { console.error('Unhandled error in failing pipeline execution (should not happen):', err); });
Debug
Known issues
gotchaForgetting to `await next()` within an asynchronous middleware function will cause the outer middleware to complete its 'after' logic immediately, before inner middleware has finished executing. This breaks the intended 'onion' model of execution.
fix
Always ensure `await next()` is used when calling the next middleware in an `async` function if you expect control to return to the current middleware after the inner stack has completed.
affects: >=1.0.0
gotchaErrors thrown by asynchronous middleware functions will result in unhandled promise rejections if not explicitly caught by a `try/catch` block within the middleware itself or by a dedicated error-handling middleware placed higher in the composition.
fix
Implement an error-handling middleware that wraps `await next()` in a `try/catch` block, or ensure individual middleware functions handle their own potential errors.
affects: >=1.0.0
gotchaWhile flexible, extensive mutation of the context object across many middleware functions without clear contracts can lead to difficult-to-debug side effects and data flow issues, especially in complex pipelines.
fix
Establish clear conventions for context properties and their expected types/values at each stage of the pipeline. Consider using immutable data patterns or a more structured context object where applicable.
affects: >=1.0.0
Errors
Common errors & fixes
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing an error inside an async function without a catch block, or by rejecting a promise which was not handled with .catch().
An asynchronous middleware function threw an error, and no upstream middleware in the pipeline or the final `.catch()` handler on the composed app caught it.
fix
Wrap `await next()` calls in a `try/catch` block within your middleware, or ensure an error-handling middleware is correctly positioned at the beginning of your pipeline to catch errors from subsequent middleware.
TypeError: next is not a function
A function passed into `compose` did not correctly receive `(ctx, next)` arguments, or `next()` was called outside its scope or with incorrect context.
fix
Ensure all functions passed to `compose` adhere to the `async (ctx, next)` signature, even if `next` is not used. Verify the order of arguments.
My outer middleware log appeared before my inner middleware log, but it should have been after!
The `await` keyword was omitted when calling `next()` in an `async` middleware function, causing the outer middleware to proceed before the inner middleware completed.
fix
Always use `await next()` in `async` middleware functions to ensure the 'onion' model's control flow is maintained and execution returns to the current middleware after the inner stack is complete.
Upgrade
Version history
7.0.4latest on PyPI
Audit
Dependencies

No dependency data recorded yet.

Agent activity
20 hits · last 30 days
claudebot
4
ahrefsbot
3
node
2
amazonbot
2
bytedance
2
Amazon
1
Resources