{"id":17975,"library":"tamper","title":"tamper - Response Body Middleware","description":"tamper is a Node.js middleware designed for intercepting and modifying HTTP response bodies before they are sent to the client. It provides a simple API for Connect/Express-compatible applications, allowing developers to inspect request and response headers and conditionally apply transformations to the response body. The current stable version, 1.1.0, indicates a mature but largely feature-complete codebase with infrequent updates. Its primary differentiation lies in its focused scope of response body manipulation, offering a callback-based or Promise-based mechanism for transformations. It's particularly useful for tasks like injecting scripts, performing server-side content rewrites, or debugging response payloads without directly altering original handlers. It ships with TypeScript types, enhancing developer experience for type-safe applications.","status":"maintenance","version":"1.1.0","language":"javascript","source_language":"en","source_url":"https://github.com/fgnass/tamper","tags":["javascript","connect","middleware","capture","modify","response","typescript"],"install":[{"cmd":"npm install tamper","lang":"bash","label":"npm"},{"cmd":"yarn add tamper","lang":"bash","label":"yarn"},{"cmd":"pnpm add tamper","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Common framework for using `tamper` middleware.","package":"express","optional":true},{"reason":"Core middleware framework that `tamper` is compatible with.","package":"connect","optional":true}],"imports":[{"note":"As of v1.1.0, 'tamper' is a CommonJS module. Direct ES module `import` syntax will not work without specific Node.js or bundler configuration.","wrong":"import tamper from 'tamper';","symbol":"tamper","correct":"const tamper = require('tamper');"},{"note":"The `tamper` function itself is the default export. You can type the returned middleware function using standard Express/Connect types.","wrong":"import type { TamperMiddleware } from 'tamper';","symbol":"Middleware","correct":"import { Request, Response, NextFunction } from 'express';\nconst tamper = require('tamper');\n\n// To type the result of tamper()\ntype TamperHandler = (req: Request, res: Response, next: NextFunction) => void;"}],"quickstart":{"code":"import express, { Request, Response, NextFunction } from 'express';\nimport tamper from 'tamper'; // This would actually be 'const tamper = require(\"tamper\")' for CJS\n\n// For demonstration, let's pretend tamper supports ESM or use require syntax\nconst app = express();\n\napp.use(tamper(function(req: Request, res: Response) {\n  // Only modify HTML responses\n  if (res.getHeader('Content-Type')?.toString().includes('text/html')) {\n    console.log(`Tampering with HTML response for ${req.url}`);\n    // Return a function to capture and modify the body\n    return function(body: string) {\n      // Replace all occurrences of 'foo' with 'bar'\n      // Or inject a script tag for client-side analytics\n      return body.replace(/foo/g, 'bar').replace('</body>', '<script>console.log(\"Body tampered!\")</script></body>');\n    };\n  }\n  // Return a falsy value to continue without body modification\n  return;\n}));\n\napp.get('/', (req, res) => {\n  res.status(200).set('Content-Type', 'text/html').send('<html><body><h1>Hello foo world!</h1></body></html>');\n});\n\napp.get('/json', (req, res) => {\n  res.json({ message: 'This is JSON' });\n});\n\nconst PORT = process.env.PORT ?? 3000;\napp.listen(PORT, () => {\n  console.log(`Server listening on port ${PORT}`);\n  console.log('Try visiting http://localhost:3000 and http://localhost:3000/json');\n});\n","lang":"typescript","description":"Demonstrates basic usage of `tamper` middleware with Express, showing how to conditionally modify HTML response bodies and leave other content types untouched."},"warnings":[{"fix":"Monitor memory usage for applications handling large responses. Limit `tamper` usage to specific routes or content types known to be small.","message":"Modifying response bodies implies buffering the entire response in memory. For very large responses, this can lead to significant memory consumption and increased latency. Consider alternatives for streaming modifications if performance is critical for large files.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure `tamper` is configured correctly, and test responses with client-side tools to verify integrity. In some cases, it might be necessary to manually `res.removeHeader('Content-Length')` if issues persist.","message":"When modifying a response body, the `Content-Length` HTTP header (if present) becomes invalid. Clients relying on this header might receive truncated or incomplete data. `tamper` attempts to handle this, but manual verification is recommended.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always place `tamper` middleware *before* any compression middleware (e.g., `express.compress()`, `compression`) in your middleware stack. This ensures `tamper` operates on the uncompressed text.","message":"If compression middleware (e.g., `compression`) is used *after* `tamper`, `tamper` will receive the uncompressed body, but the `Content-Length` issue still applies. If `compression` is used *before* `tamper`, `tamper` will receive and attempt to modify the compressed binary body, which will result in corrupted output.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Continue using `const tamper = require('tamper');` for CommonJS compatibility. If strictly needing ESM, consider writing a wrapper or using dynamic `import()` within an async function, though this may complicate middleware chaining.","message":"`tamper` v1.x is a CommonJS module. Attempting to import it using ES module syntax (`import tamper from 'tamper';`) will fail in Node.js environments unless specific experimental flags or bundler configurations are used. This can be a breaking change when migrating older CJS applications to a modern ESM-first setup.","severity":"breaking","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"As `tamper` is a CommonJS module, you need to use `import tamper from 'tamper'` with a bundler that handles CJS-to-ESM conversion, or switch your file to CommonJS (`.cjs` or `package.json` `\"type\": \"commonjs\"`).","cause":"Attempting to use `require` in an ES module file (`.mjs` or `package.json` `\"type\": \"module\"`).","error":"ReferenceError: require is not defined in ES module scope"},{"fix":"Run `npm install tamper` or `yarn add tamper` to install the package. Verify the package is listed in `node_modules` and that `require('tamper')` is spelled correctly.","cause":"The `tamper` package is not installed or the import/require path is incorrect.","error":"Error: Cannot find module 'tamper'"},{"fix":"Always ensure your `tamper` logic explicitly checks `res.getHeader('Content-Type')` to only process `text/html`, `text/plain`, or other expected string-based content types. Place `tamper` before compression middleware.","cause":"This can sometimes occur when attempting to modify binary or already compressed data as if it were a string, or if `Content-Length` becomes severely mismatched.","error":"RangeError: Invalid array length"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}