MCPcopy Index your code
hub / github.com/chimurai/http-proxy-middleware

github.com/chimurai/http-proxy-middleware @v4.1.1 sqlite

repository ↗ · DeepWiki ↗ · release v4.1.1 ↗
114 symbols 456 edges 85 files 5 documented · 4% 49 cross-repo links
README

http-proxy-middleware

GitHub Workflow Status (with branch) Coveralls Known Vulnerabilities npm

Node.js proxying made simple. Configure proxy middleware with ease for connect, express, next.js, hono and many more.

Powered by httpxy. A maintained version of http-proxy.

⚠️ Note

This page is showing documentation for version v4.x.x (release notes)

For older documentation:

TL;DR

Proxy /api requests to http://www.example.org

:bulb: Tip: Set the option changeOrigin to true for name-based virtual hosted sites.

// typescript
import express from 'express';
import type { NextFunction, Request, Response } from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware';
import type { Filter, Options, RequestHandler } from 'http-proxy-middleware';

const app = express();

const proxyMiddleware = createProxyMiddleware<Request, Response>({
  target: 'http://www.example.org/api',
  changeOrigin: true,
});

app.use('/api', proxyMiddleware);

app.listen(3000);

// proxy and keep the same base path "/api"
// http://127.0.0.1:3000/api/foo/bar -> http://www.example.org/api/foo/bar

All httpxy options can be used, along with some extra http-proxy-middleware options.

Table of Contents

Install

npm install --save-dev http-proxy-middleware

Basic usage

Create and configure a proxy middleware with: createProxyMiddleware(config).

import { createProxyMiddleware } from 'http-proxy-middleware';

const apiProxy = createProxyMiddleware({
  target: 'http://www.example.org',
  changeOrigin: true,
});

// 'apiProxy' is now ready to be used as middleware in a server.

Express Server Example

An example with express server.

// include dependencies
import express from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware';

const app = express();

// create the proxy
/** @type {import('http-proxy-middleware').RequestHandler<import('express').Request, import('express').Response>} */
const exampleProxy = createProxyMiddleware({
  target: 'http://www.example.org/api', // target host with the same base path
  changeOrigin: true, // needed for virtual hosted sites
});

// mount `exampleProxy` in web server
app.use('/api', exampleProxy);
app.listen(3000);

app.use(path, proxy)

If you want to use the server's app.use path parameter to match requests. Use pathFilter option to further include/exclude requests which you want to proxy.

app.use(
  createProxyMiddleware({
    target: 'http://www.example.org/api',
    changeOrigin: true,
    pathFilter: '/api/proxy-only-this-path',
  }),
);

app.use documentation:

Options

http-proxy-middleware options:

pathFilter (string, []string, glob, []glob, function)

Narrow down which requests should be proxied. The path used for filtering is the request.url pathname. In Express, this is the path relative to the mount-point of the proxy.

  • path matching
  • createProxyMiddleware({...}) - matches any path, all requests will be proxied when pathFilter is not configured.
  • createProxyMiddleware({ pathFilter: '/api', ...}) - matches paths starting with /api

  • multiple path matching

  • createProxyMiddleware({ pathFilter: ['/api', '/ajax', '/someotherpath'], ...})

  • wildcard path matching

For fine-grained control you can use wildcard matching. Glob pattern matching is done by micromatch. Visit micromatch or glob for more globbing examples. - createProxyMiddleware({ pathFilter: '**', ...}) matches any path, all requests will be proxied. - createProxyMiddleware({ pathFilter: '**/*.html', ...}) matches any path which ends with .html - createProxyMiddleware({ pathFilter: '/*.html', ...}) matches paths directly under path-absolute - createProxyMiddleware({ pathFilter: '/api/**/*.html', ...}) matches requests ending with .html in the path of /api - createProxyMiddleware({ pathFilter: ['/api/**', '/ajax/**'], ...}) combine multiple patterns - createProxyMiddleware({ pathFilter: ['/api/**', '!**/bad.json'], ...}) exclusion

Note: In multiple path matching, you cannot use string paths and wildcard paths together.

  • custom matching

For full control you can provide a custom function to determine which requests should be proxied or not.

```javascript /* * @return {Boolean} / const pathFilter = function (path, req) { return path.match('^/api') && req.method === 'GET'; };

const apiProxy = createProxyMiddleware({ target: 'http://www.example.org', pathFilter: pathFilter, }); ```

pathRewrite (object/function)

Rewrite target's url path. Object-keys will be used as RegExp to match paths.

// rewrite path
pathRewrite: {'^/old/api' : '/new/api'}

// remove path
pathRewrite: {'^/remove/api' : ''}

// add base path
pathRewrite: {'^/' : '/basepath/'}

// custom rewriting
pathRewrite: function (path, req, res, options) { return path.replace('/api', '/base/api') }

// custom rewriting, returning Promise
pathRewrite: async function (path, req, res, options) {
  const should_add_something = await httpRequestToDecideSomething(path);
  if (should_add_something) path += "something";
  return path;
}

// `res` is undefined in WebSocket upgrade flows.

router (object/function)

Re-target option.target for specific requests.

// Use `host` and/or `path` to match requests. First match will be used.
// The order of the configuration matters.
router: {
    'integration.localhost:3000' : 'http://127.0.0.1:8001',  // host only
    'staging.localhost:3000'     : 'http://127.0.0.1:8002',  // host only
    'localhost:3000/api'         : 'http://127.0.0.1:8003',  // host + path
    '/rest'                      : 'http://127.0.0.1:8004'   // path only
}

// Custom router function (string target)
router: function(req, res, options) {
    return 'http://127.0.0.1:8004';
}

// Custom router function (target object)
router: function(req, res, options) {
    return {
        protocol: 'https:', // The : is required
        host: '127.0.0.1',
        port: 8004
    };
}

// Asynchronous router function which returns promise
router: async function(req, res, options) {
    const url = await doSomeIO();
    return url;
}

// NOTE: `res` is undefined in WebSocket upgrade flows.

plugins (Array)

const simpleRequestLogger = (proxyServer, options) => {
  proxyServer.on('proxyReq', (proxyReq, req, res) => {
    console.log(`[HPM] [${req.method}] ${req.url}`); // outputs: [HPM] GET /users
  });
},

const config = {
  target: `http://example.org`,
  changeOrigin: true,
  plugins: [simpleRequestLogger],
};

ejectPlugins (boolean) default: false

If you're not satisfied with the pre-configured plugins, you can eject them by configuring ejectPlugins: true.

NOTE: register your own error handlers to prevent server from crashing.

// eject default plugins and manually add them back
import {
  debugProxyErrorsPlugin, // subscribe to proxy errors to prevent server from crashing
  errorResponsePlugin, // return 5xx response on proxy error
  loggerPlugin, // log proxy events to a logger (ie. console)
  proxyEventsPlugin, // implements the "on:" option
} from 'http-proxy-middleware';

createProxyMiddleware({
  target: `http://example.org`,
  changeOrigin: true,
  ejectPlugins: true,
  plugins: [debugProxyErrorsPlugin, loggerPlugin, errorResponsePlugin, proxyEventsPlugin],
});

definePlugin helper

Create your own http-proxy-middleware plugin.

(Default plugins are created with definePlugin)

import { createProxyMiddleware, definePlugin } from 'http-proxy-middleware';

const myPlugin = definePlugin((proxyServer, options) => {
  // plugin implementation
});

// use configure and use plugin
createProxyMiddleware({
  target: `http://example.org`,
  plugins: [myPlugin],
});

logger (Object)

Configure a logger to output information from http-proxy-middleware: ie. console, winston, pino, bunyan, log4js, etc...

Only info, warn, error are used internally for compatibility across different loggers.

If you use winston, make sure to enable interpolation: https://github.com/winstonjs/winston#string-interpolation

See also logger recipes (recipes/logger.md) for more details.

createProxyMiddleware({
  logger: console,
});

httpxy events

Subscribe to httpxy events with the on option:

createProxyMiddleware({
  target: 'http://www.example.org',
  on: {
    proxyReq: (proxyReq, req, res) => {
      /* handle proxyReq */
    },
    proxyRes: (proxyRes, req, res) => {
      /* handle proxyRes */
    },
    error: (err, req, res) => {
      /* handle error */
    },
  },
});
  • option.on.error: function, subscribe to httpxy's error event for custom error handling.

javascript function onError(err, req, res, target) { res.writeHead(500, { 'Content-Type': 'text/plain', }); res.end('Something went wrong. And we are reporting a custom error message.'); }

  • option.on.proxyRes: function, subscribe to httpxy's proxyRes event.

javascript function onProxyRes(proxyRes, req, res) { proxyRes.headers['x-added'] = 'foobar'; // add new header to response delete proxyRes.headers['x-removed']; // remove header from response }

  • option.on.proxyReq: function, subscribe to httpxy's proxyReq event.

javascript function onProxyReq(proxyReq, req, res) { // add custom header to request proxyReq.setHeader('x-added', 'foobar'); // or log the req }

  • option.on.proxyReqWs: function, subscribe to httpxy's proxyReqWs event.

javascript function onProxyReqWs(proxyReq, req, socket, options, head) { // add custom header proxyReq.setHeader('X-Special-Proxy-Header', 'foobar'); }

  • option.on.open: function, subscribe to httpxy's open event.

javascript function onOpen(proxySocket) { // listen for messages coming FROM the target here proxySocket.on('data', hybridParseAndLogMessage); }

  • option.on.close: function, subscribe to httpxy's close event.

javascript function onClose(res, socket, head) { // view disconnected websocket connections console.log('Client disconnected'); }

httpxy options

The following options are provided by the underlying httpxy library.

  • option.target: url string to be parsed with the url module
  • option.forward

Extension points exported contracts — how you extend this code

MyRequest (Interface)
(no doc)
test/types.spec.ts
RequestHandler (Interface)
(no doc)
src/types.ts
MyResponse (Interface)
(no doc)
test/types.spec.ts
Plugin (Interface)
(no doc)
src/types.ts
OnProxyEvent (Interface)
(no doc)
src/types.ts
Options (Interface)
(no doc)
src/types.ts

Core symbols most depended-on inside this repo

createProxyMiddleware
called by 89
src/factory.ts
createApp
called by 69
test/e2e/test-kit.ts
matchPathFilter
called by 49
src/path-filter.ts
createMockRequest
called by 23
test/test-utils.ts
createUrl
called by 21
src/utils/create-url.ts
fixRequestBody
called by 20
src/handlers/fix-request-body.ts
getTarget
called by 17
src/router.ts
stringifyFormData
called by 17
src/handlers/fix-request-body-utils/stringify-form-data.ts

Shape

Function 99
Interface 6
Class 4
Method 4
Enum 1

Languages

TypeScript100%

Modules by API surface

test/types.spec.ts10 symbols
test/e2e/websocket.spec.ts8 symbols
src/path-filter.ts8 symbols
src/utils/ipv6.ts6 symbols
src/router.ts5 symbols
src/http-proxy-middleware.ts5 symbols
test/unit/fix-request-body.spec.ts4 symbols
test/e2e/test-kit.ts4 symbols
src/types.ts4 symbols
src/path-rewriter.ts4 symbols
src/handlers/response-interceptor.ts4 symbols
src/handlers/fix-request-body-utils/stringify-form-data.ts4 symbols

Dependencies from manifests, versioned

@commitlint/cli21.0.2 · 1×
@commitlint/config-conventional21.0.2 · 1×
@eslint/js10.0.1 · 1×
@fastify/express4.0.6 · 1×
@hono/node-server2.0.4 · 1×
@types/debug4.1.13 · 1×
@types/eslint9.6.1 · 1×
@types/express5.0.6 · 1×
@types/is-glob4.0.4 · 1×
@types/micromatch4.0.10 · 1×
@types/node24.10.2 · 1×
@types/react19 · 1×

For agents

$ claude mcp add http-proxy-middleware \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact