Node.js HTTP Proxy Server
The `proxy` package provides a programmatic HTTP(S) proxy server API for Node.js, allowing developers to script custom proxy logic. Its current stable version is `4.0.0`, which notably raised the minimum Node.js requirement to version 20. The project maintains an active release cadence, with recent updates across its associated `proxy-agent` ecosystem, ensuring compatibility and improvements. Key differentiators include its simple `createProxy` API for building custom proxy servers, similar to established solutions like Squid or Privoxy, but integrated directly within a Node.js environment. It supports both standard HTTP proxying and the HTTP `CONNECT` method for tunneling. The package also includes a companion CLI tool for quick server spawning.
Common errors
-
Error [ERR_REQUIRE_ESM]: require() of ES Module .../node_modules/proxy/index.js from ... not supported.
cause Attempting to `require()` the `proxy` package in a CommonJS module when the package is primarily designed as an ES Module since v4.0.0.fixChange your import statement to `import { createProxy } from 'proxy';` and ensure your `package.json` has `'type': 'module'` or use a file extension like `.mjs` for your module. -
Error: listen EADDRINUSE: address already in use :::3128
cause Another process is already listening on the port (default 3128) that the proxy server is trying to bind to.fixEither stop the conflicting process or configure the proxy server to listen on a different port using `server.listen(PORT)` in the API or the `-p`/`--port` option with the CLI tool. -
HTTP/1.1 407 Proxy Authentication Required
cause The proxy server is configured to require authentication (e.g., via `server.authenticate` or the CLI's `--authenticate` option), but the client request did not provide valid `Proxy-Authorization` headers.fixEnsure the client sending requests through the proxy provides a correctly formatted `Proxy-Authorization` header with valid credentials (e.g., `Proxy-Authorization: Basic <base64_encoded_username:password>`).
Warnings
- breaking Version 4.0.0 of `proxy` and its related packages (e.g., `socks-proxy-agent`) now require Node.js version 20 or higher. Older Node.js versions are no longer supported.
- breaking The `package.json` exports have been simplified in v4.0.0, removing 'unnecessary imports restriction'. This change, while intended to streamline module resolution, might affect how some bundlers or CJS environments consume the package. ESM is the primary target.
- gotcha Using the CLI's `--authenticate` option with shell commands (e.g., `proxy --authenticate 'if [...] then exit 0'`) introduces potential security risks if not handled carefully. Command injection vulnerabilities could arise if input variables are not properly escaped.
- gotcha When configuring the proxy with `--local-address` or `localAddress` in the API, the specified IP address must be an available local network interface. Incorrectly configured addresses will prevent the proxy from binding or forwarding requests.
Install
-
npm install proxy -
yarn add proxy -
pnpm add proxy
Imports
- createProxy
const { createProxy } = require('proxy');import { createProxy } from 'proxy'; - http
import * as http from 'http';
- ProxyServer
import { ProxyServer } from 'proxy/dist/types';
Quickstart
import * as http from 'http';
import { createProxy } from 'proxy';
const server = createProxy(http.createServer());
// Basic authorization example (replace with real auth for production)
server.authenticate = function (req, fn) {
const auth = req.headers['proxy-authorization'];
if (auth && auth.startsWith('Basic ')) {
const credentials = Buffer.from(auth.slice(6), 'base64').toString().split(':');
const [username, password] = credentials;
if (username === 'user' && password === 'password') {
return fn(null, true);
}
}
fn(null, false);
};
server.listen(3128, () => {
const address = server.address();
const port = typeof address === 'string' ? address : address?.port;
console.log('HTTP(s) proxy server listening on port %d', port);
});