Node.js HTTP Proxy Middleware
http-proxy-middleware is a robust and flexible Node.js library designed to easily set up reverse proxies within various HTTP server frameworks such as Express, Connect, Next.js, Fastify, and Polka. It leverages http-proxy under the hood, providing a 'one-liner' API to proxy requests, handle WebSockets, rewrite paths, and modify requests/responses. The current stable major version is 3.x (specifically v3.0.5 as of recent updates), with v4.0.0 actively under development in beta, introducing some breaking changes and refinements. The library is known for its ease of integration and comprehensive configuration options, making it a popular choice for development environments and API gateway setups where requests need to be routed to different backend services. Patch releases are frequent, addressing bugs and minor improvements.
Common errors
-
TypeError: app.use() requires a middleware function
cause `createProxyMiddleware` was called with invalid arguments or no arguments, returning `undefined` instead of a function.fixEnsure `createProxyMiddleware` is called with a valid context string/array or an options object. Example: `app.use('/api', createProxyMiddleware({ target: 'http://localhost:5000' }));` -
Proxy error: connect ECONNREFUSED
cause The target server specified in `options.target` is not running or is unreachable at the given address and port.fixVerify that your target server is running and accessible from where your Node.js application is running. Check the `target` URL for typos and correct port. -
Error: The 'path' argument must be of type string. Received type undefined
cause Often related to incorrect `pathRewrite` configuration, where the rewrite function or object results in an undefined path.fixDouble-check your `pathRewrite` regular expressions and replacement strings to ensure they always resolve to a valid string. For object-based rewrites, verify the keys match the incoming path segments. -
Error: Can't set headers after they are sent to the client.
cause This error typically occurs when your application attempts to send a response or modify headers after the proxy has already initiated a response to the client.fixEnsure custom `onProxyReq` or `onProxyRes` handlers do not implicitly or explicitly send responses. If you need to handle errors or custom responses, do so before the proxy sends its own response, or ensure your custom handlers are aware of the proxy's lifecycle.
Warnings
- breaking The `legacyCreateProxyMiddleware` function has been removed. Users should migrate to `createProxyMiddleware` for all new and existing proxy configurations.
- breaking Node.js engine requirements have been updated. Older Node.js versions are no longer supported.
- gotcha The `changeOrigin` option is crucial for correctly proxying to virtual hosted sites or APIs that rely on the `Host` header. Failing to set it can lead to 404s or incorrect routing on the target server.
- gotcha When proxying requests that contain a body (POST, PUT), if you have body parsing middleware (e.g., `express.json()`, `express.urlencoded()`) applied *before* `http-proxy-middleware`, the proxy might receive an empty body because the parsing middleware has consumed it. Use `fixRequestBody` option if necessary.
Install
-
npm install http-proxy-middleware -
yarn add http-proxy-middleware -
pnpm add http-proxy-middleware
Imports
- createProxyMiddleware
const createProxyMiddleware = require('http-proxy-middleware');import { createProxyMiddleware } from 'http-proxy-middleware'; - Options
import { Options } from 'http-proxy-middleware';import type { Options } from 'http-proxy-middleware'; - legacyCreateProxyMiddleware
import { legacyCreateProxyMiddleware } from 'http-proxy-middleware';This symbol is removed in v4.0.0-beta.0. Use `createProxyMiddleware` instead.
Quickstart
import express from 'express';
import { createProxyMiddleware, Options } from 'http-proxy-middleware';
const app = express();
const port = 3000;
// Configuration for the proxy middleware
const apiProxyOptions: Options = {
target: 'http://jsonplaceholder.typicode.com', // target host
changeOrigin: true, // needed for virtual hosted sites
ws: true, // proxy websockets
pathRewrite: {
'^/api': '', // rewrite path: remove `/api` prefix when forwarding to target
},
onProxyReq: (proxyReq, req, res) => {
// Optional: Log proxy request details or modify headers
console.log(`[Proxy] Proxying request: ${req.method} ${req.url} -> ${proxyReq.path}`);
},
onProxyRes: (proxyRes, req, res) => {
// Optional: Log proxy response details or modify response headers
console.log(`[Proxy] Received response for: ${req.url} with status: ${proxyRes.statusCode}`);
},
onError: (err, req, res, target) => {
console.error(`[Proxy Error] ${err.message}`);
res.status(500).send('Proxy Error');
}
};
// Apply the proxy middleware to '/api' route
app.use('/api', createProxyMiddleware(apiProxyOptions));
// Basic route for the main application
app.get('/', (req, res) => {
res.send('Hello from the main application!');
});
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
console.log(`Try accessing http://localhost:${port}/api/todos/1`);
});
// To run this:
// 1. npm init -y
// 2. npm install express http-proxy-middleware @types/express @types/http-proxy-middleware typescript ts-node
// 3. Add "start": "ts-node app.ts" to package.json scripts
// 4. npm start