{"id":16024,"library":"express-http-proxy","title":"Express HTTP Proxy Middleware","description":"express-http-proxy is an Express.js middleware designed for proxying incoming HTTP requests to a specified target host. It offers extensive customization through hooks, enabling developers to modify incoming requests before they reach the proxy target and decorate outgoing responses before they are returned to the client. The package is currently at version 2.1.2 and is actively maintained, having received updates like the significant v2.0.0 release that upgraded underlying dependencies and ensured compatibility with modern Node.js environments (16, 18, and 20). While not on a strict, frequent release cadence, updates are issued to address compatibility and dependency needs, especially for critical Node.js versions. Its key differentiator lies in its comprehensive set of configurable hooks for request and response transformation, making it suitable for scenarios requiring fine-grained control over proxy behavior within an Express application, such as API gateways or hiding internal service endpoints.","status":"active","version":"2.1.2","language":"javascript","source_language":"en","source_url":"git://github.com/villadora/express-http-proxy","tags":["javascript","express-http-proxy"],"install":[{"cmd":"npm install express-http-proxy","lang":"bash","label":"npm"},{"cmd":"yarn add express-http-proxy","lang":"bash","label":"yarn"},{"cmd":"pnpm add express-http-proxy","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"express-http-proxy is an Express.js middleware and requires Express to function.","package":"express","optional":false},{"reason":"Provides TypeScript type definitions for the package.","package":"@types/express-http-proxy","optional":true}],"imports":[{"note":"This is the CommonJS `require` syntax for Node.js environments. The package exports the middleware function as its default.","wrong":"import proxy from 'express-http-proxy';","symbol":"proxy","correct":"const proxy = require('express-http-proxy');"},{"note":"For ESM environments, `express-http-proxy` exports the middleware function as its default export.","wrong":"import { proxy } from 'express-http-proxy';","symbol":"proxy","correct":"import proxy from 'express-http-proxy';"},{"note":"Requires `@types/express-http-proxy` to be installed (e.g., `npm install --save-dev @types/express-http-proxy`). This imports types for configuring the proxy.","wrong":"import { ProxyOptions } from 'express-http-proxy';","symbol":"ProxyOptions","correct":"import type { ProxyOptions } from 'express-http-proxy';"}],"quickstart":{"code":"import express from 'express';\nimport proxy from 'express-http-proxy';\nimport type { Request, Response, NextFunction } from 'express';\n\nconst app = express();\nconst PORT = process.env.PORT || 3000;\nconst PROXY_TARGET = process.env.PROXY_TARGET || 'https://httpbin.org'; // A public test service\n\n// Middleware to log all incoming requests before proxying\napp.use((req: Request, res: Response, next: NextFunction) => {\n  console.log(`Incoming request: ${req.method} ${req.originalUrl}`);\n  next();\n});\n\n// Configure the proxy middleware\napp.use(\n  '/proxy',\n  proxy(PROXY_TARGET, {\n    // Resolve the path for the proxied request\n    proxyReqPathResolver: (req: Request) => {\n      const resolvedPath = req.url.startsWith('/proxy') ? req.url.slice('/proxy'.length) : req.url;\n      console.log(`Resolved proxy path to: ${resolvedPath}`);\n      return resolvedPath;\n    },\n    // Decorate the request going to the proxy target\n    decorateProxyReq: (proxyReq: any, req: Request) => {\n      console.log(`Adding custom header to proxied request for ${req.path}`);\n      proxyReq.setHeader('X-Proxy-By', 'express-http-proxy-example');\n      return proxyReq;\n    },\n    // Decorate the response coming back from the proxy target\n    decorateUserRes: (proxyRes: any, proxyResData: Buffer, userReq: Request, userRes: Response) => {\n      console.log(`Received proxied response status: ${proxyRes.statusCode}`);\n      // Example: modify response data (e.g., inject a footer)\n      const data = proxyResData.toString('utf8');\n      if (proxyRes.headers['content-type']?.includes('text/html')) {\n        return data.replace('</body>', '<p><i>Proxied via express-http-proxy!</i></p></body>');\n      }\n      return proxyResData; // Return original data if not HTML\n    },\n    // Custom error handler for proxy errors\n    proxyErrorHandler: (err: any, res: Response, next: NextFunction) => {\n      console.error('Proxy error:', err);\n      res.status(500).send('Proxy Error: Could not reach target.');\n    }\n  })\n);\n\n// Default route for non-proxied requests\napp.get('/', (req: Request, res: Response) => {\n  res.send('Hello from the main Express app! Try /proxy/get to use the proxy.');\n});\n\napp.listen(PORT, () => {\n  console.log(`Server running on http://localhost:${PORT}`);\n  console.log(`Proxying requests from /proxy to ${PROXY_TARGET}`);\n  console.log(`Try visiting http://localhost:${PORT}/proxy/get for a proxied request.`);\n});","lang":"typescript","description":"This example sets up an Express server with `express-http-proxy` to forward requests from `/proxy` to `httpbin.org`. It demonstrates request/response logging, custom header injection, HTML response modification, and basic error handling."},"warnings":[{"fix":"Upgrade your Node.js runtime environment to version 16, 18, or 20 to ensure compatibility and stability.","message":"Version 2.0.0 and above explicitly target Node.js 16, 18, and 20 for compatibility. Running on older Node.js versions (e.g., Node.js 14 or earlier) may lead to unexpected behavior or runtime errors due to updated underlying dependencies.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Review existing `decorateUserRes` or similar response decorators to ensure they correctly handle streamed data or explicitly buffer the response data if necessary within the decorator.","message":"As of approximately v1.2.0 (referenced as v.1.20 in release notes), `express-http-proxy` defaults to streaming proxy responses. This can alter behavior if your application previously relied on buffered responses or expected specific non-streaming handling, potentially affecting custom response decorators.","severity":"gotcha","affected_versions":">=1.2.0"},{"fix":"Increase the timeout using the `timeout` option in `express-http-proxy`'s configuration, and also consider increasing `req.setTimeout()` on the Express request object if the issue persists on the client side. Ensure this timeout is sufficiently higher than the expected response time from the upstream service.","message":"Node.js's default HTTP request timeout is 2 minutes. Long-running proxied requests exceeding this duration may result in `504 Gateway Timeout` errors or `ECONNRESET` messages. `express-http-proxy` itself may reset the connection with an `x-timeout-reason` header.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Configure Express's `body-parser` (or equivalent) with a higher `limit` option, e.g., `app.use(express.json({ limit: '50mb' }));`. Additionally, ensure `express-http-proxy` itself is not implicitly buffering large bodies beyond configurable limits.","message":"When proxying requests with large bodies (e.g., file uploads), you may encounter an `Error: request entity too large`. This often occurs because Express or underlying body parsers have default size limits that are exceeded by the proxied request.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always sanitize and validate any user-provided hostnames or URLs used in the `proxyReqPathResolver` or the initial `proxy` function argument. Use a whitelist of allowed target hosts or implement robust input validation to prevent malicious redirection.","message":"Improper configuration of `express-http-proxy`, particularly allowing user-controlled input to determine the proxy target host without strict validation, can lead to an open proxy or Server-Side Request Forgery (SSRF) vulnerabilities.","severity":"gotcha","affected_versions":"*"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure that your custom `decorateUserRes` or `proxyErrorHandler` functions do not attempt to send a response or modify headers on the `userRes` object if `express-http-proxy` has already done so. Use `res.headersSent` to check if headers have already been sent before attempting modification.","cause":"This error typically occurs when a response is attempted to be modified or sent more than once within the Express middleware chain, often after the proxy has already sent its response.","error":"Error: Can't set headers after they are sent to the client."},{"fix":"Verify that the target host specified in `proxy(host, options)` is correct and that the target server is running and accessible from the machine running your Express application. Check firewalls or network configurations if the target is external.","cause":"The `express-http-proxy` middleware attempted to connect to the target host but was refused, or the DNS resolution failed. This usually means the target server is down, unreachable, or the hostname is incorrect.","error":"connect ECONNREFUSED 127.0.0.1:80 (or similar network error like getaddrinfo EAI_AGAIN)"},{"fix":"Install the type definitions: `npm install --save-dev @types/express-http-proxy`. Ensure your `tsconfig.json` includes `node_modules/@types` in its `typeRoots` or that the types are correctly picked up by your IDE.","cause":"When using TypeScript, this error indicates that the type definitions for `express-http-proxy` are not correctly installed or configured, so TypeScript cannot infer the `proxy` function's signature.","error":"Property 'proxy' does not exist on type 'typeof import(\"/.../node_modules/express-http-proxy/index\")'."},{"fix":"Increase the `timeout` option within the `express-http-proxy` configuration, e.g., `proxy(host, { timeout: 120000 })` for 120 seconds. If the issue persists, examine the performance of the upstream service or network latency.","cause":"The proxied request took too long to receive a response from the upstream target, exceeding either Node.js's default HTTP timeout or a custom timeout configured in `express-http-proxy`.","error":"504 Gateway Timeout or an 'x-timeout-reason: express-http-proxy reset the request' header in the response."}],"ecosystem":"npm"}