{"id":17069,"library":"trough","title":"Trough Middleware Pipeline","description":"`trough` is a lightweight, promise-aware middleware utility designed for building flexible processing pipelines in JavaScript and TypeScript environments. Currently at version 2.2.0, it is actively maintained with a consistent release cadence for minor improvements and bug fixes, typically addressing specific use cases or compatibility enhancements. Unlike some traditional middleware solutions, `trough` allows each stage of the pipeline to modify the input for subsequent stages and seamlessly integrates both synchronous and asynchronous functions, including those that return promises or use Node.js-style callbacks. Its core differentiator lies in its minimal API and explicit control over data flow, making it suitable for scenarios like plugin systems or data transformation pipelines. It is an ESM-only package, targeting modern Node.js (v16+) and browser environments via `esm.sh`.","status":"active","version":"2.2.0","language":"javascript","source_language":"en","source_url":"https://github.com/wooorm/trough","tags":["javascript","middleware","ware","typescript"],"install":[{"cmd":"npm install trough","lang":"bash","label":"npm"},{"cmd":"yarn add trough","lang":"bash","label":"yarn"},{"cmd":"pnpm add trough","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"trough is ESM-only since v2.0.0. CommonJS `require` is not supported.","wrong":"const trough = require('trough')","symbol":"trough","correct":"import { trough } from 'trough'"},{"note":"`wrap` is a named export, also ESM-only. Ensure correct named import syntax.","wrong":"const { wrap } = require('trough')","symbol":"wrap","correct":"import { wrap } from 'trough'"},{"note":"trough ships with TypeScript types. Import types using `import type` for clarity and better tooling.","symbol":"Pipeline","correct":"import type { Pipeline } from 'trough'"},{"note":"Specific type imports like `Middleware` or `Callback` enhance type safety in TypeScript projects.","symbol":"Middleware","correct":"import type { Middleware } from 'trough'"}],"quickstart":{"code":"import fs from 'node:fs'\nimport path from 'node:path'\nimport process from 'node:process'\nimport {trough} from 'trough'\n\nconst pipeline = trough()\n  .use(function (fileName) {\n    console.log('Checking… ' + fileName)\n  })\n  .use(function (fileName) {\n    return path.join(process.cwd(), fileName)\n  })\n  .use(function (filePath, next) {\n    // Asynchronous middleware uses a callback\n    fs.stat(filePath, function (error, stats) {\n      next(error, {filePath, stats})\n    })\n  })\n  .use(async function (ctx) {\n    // Or use async/await for Promises\n    if (ctx.stats.isFile()) {\n      return new Promise((resolve, reject) => {\n        fs.readFile(ctx.filePath, (err, data) => {\n          if (err) reject(err); else resolve(data)\n        })\n      })\n    } else {\n      throw new Error('Expected file')\n    }\n  })\n\n// Example usage with a valid file and an invalid path\npipeline.run('readme.md', console.log)\npipeline.run('node_modules', console.log)\n","lang":"typescript","description":"This quickstart demonstrates creating a `trough` pipeline with both synchronous and asynchronous (callback and Promise-based) middleware functions, showing how data flows and errors are handled."},"warnings":[{"fix":"Refactor module imports from `const trough = require('trough')` to `import { trough } from 'trough'` in your codebase.","message":"`trough` transitioned to an ESM-only package in version 2.0.0. All CommonJS `require()` statements will fail, necessitating a migration to `import` syntax.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Ensure you are using `trough` v2.0.1 or newer if you experienced unexpected data flow issues immediately after upgrading to v2.0.0.","message":"Version 2.0.1 fixed a regression from v2.0.0 where incorrect values could be passed between middleware functions in the pipeline.","severity":"breaking","affected_versions":"2.0.0"},{"fix":"For Promise-based middleware, `return someAsyncFunction()`. For callback-based middleware, ensure `next(error, result)` is called. Refer to the API documentation for specific middleware signatures.","message":"Asynchronous middleware functions must explicitly signal completion by either returning a Promise (or a thenable) or calling the `next` (or `done`) callback provided as the last argument. Failing to do so will cause the pipeline to proceed prematurely.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure all middleware functions intended for browser execution are browser-compatible. Use bundlers like webpack or Rollup to shim Node.js modules or exclude them from browser builds if necessary.","message":"When using `trough` in a browser environment, be mindful that any middleware functions relying on Node.js-specific APIs (e.g., `fs`, `path`, `process`) will fail.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"If experiencing `this` context issues, ensure you are on v2.1.0 or newer. Use `.bind(this)` or arrow functions to explicitly control `this` when needed.","message":"While v2.1.0 added support for the `this` context within middleware functions when using the `wrap` utility, developers should still be cautious about how `this` is bound, especially when passing methods as middleware. Arrow functions may capture `this` from their lexical scope.","severity":"gotcha","affected_versions":"<2.1.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Convert your module to ESM or update your tooling configuration to handle ESM imports. Use `import { trough } from 'trough'` instead.","cause":"Attempting to use `require('trough')` in a CommonJS module or an environment that strictly enforces ESM.","error":"ERR_REQUIRE_ESM"},{"fix":"Ensure your import statement matches `import { trough } from 'trough'` and your TypeScript `tsconfig.json` `module` option is set to `ESNext` or `Node16` if targeting modern Node.js.","cause":"Incorrect import syntax, often seen when TypeScript compiles ESM to CommonJS, or when mixing default/named import styles with an ESM-only package.","error":"TypeError: (0, trough_1.trough) is not a function"},{"fix":"Refactor the problematic middleware to use browser-compatible APIs or ensure it's only run in a Node.js context. For shared code, abstract platform-specific logic.","cause":"A middleware function uses Node.js-specific globals or modules (like `process`, `fs`, `path`) but the code is being executed in a browser environment.","error":"ReferenceError: process is not defined"},{"fix":"Review the middleware that threw the error (in this case, the one checking `ctx.stats.isFile()`) and ensure the input to the pipeline, or the logic within the middleware, handles all expected cases. Implement robust error handling and input validation.","cause":"This is an example of a custom error thrown by a middleware function due to specific application logic (e.g., input validation, file type checks) that failed within the pipeline.","error":"Error: Expected file"}],"ecosystem":"npm","meta_description":null}