How to Configure Proxy Settings for API Requests in Create React App
To configure proxy settings for API requests in Create React App, add a proxy string to your package.json for simple setups, or create a src/setupProxy.js file using http-proxy-middleware for advanced configurations like path rewriting or multiple targets.
When you run npm start in a Create React App (CRA) project, the development server needs to forward API requests to your backend. Configuring proxy settings for API requests prevents CORS issues during development and allows your React app to communicate with servers running on different ports.
How the Proxy Works Under the Hood
CRA's development server is powered by webpack-dev-server with an Express backend. The proxy logic is implemented in packages/react-dev-utils/WebpackDevServerUtils.js within the prepareProxy function (lines 302-389), which is invoked by the start script in packages/react-scripts/scripts/start.js.
Reading the Proxy Field
When you run npm start, the development server loads your project's package.json and extracts the value from the proxy field. This value is passed directly to prepareProxy for validation and middleware creation.
Validation in prepareProxy
The prepareProxy function enforces strict validation rules:
- The proxy value must be a string beginning with
http://orhttps:// - On Windows, the target URL is normalized via
resolveLoopbackto prevent IPv6-related connection issues
If validation fails, the development server exits with a descriptive error message.
Middleware Creation and Configuration
Once validated, prepareProxy returns an array containing an http-proxy-middleware configuration object with these critical settings:
- Context function: Determines which requests get proxied. Non-GET requests are always proxied. GET requests are proxied only when the request does not accept
text/html, ensuring that SPA navigation requests serve the React app rather than being forwarded to the API. - onProxyReq: Rewrites the
Originheader to match the target URL, eliminating CORS errors during development. - onError: Logs helpful error messages when the backend server is unreachable.
- Standard options:
secure: false,changeOrigin: true,ws: true(WebSocket support), andxfwd: true.
Host-Check Hardening
Enabling a proxy automatically activates stricter host-header validation to protect against DNS rebinding attacks. If you need to disable this check—for example, when developing on a remote host—set DANGEROUSLY_DISABLE_HOST_CHECK=true in .env.development.local. Warning: This disables a critical security mitigation and should only be used on trusted networks.
Fallback to setupProxy.js
For complex scenarios requiring multiple backends, path rewriting, or custom headers, CRA supports an optional src/setupProxy.js file. When present, the dev server automatically requires this file and passes the Express app instance, allowing you to register any number of custom proxy middlewares using http-proxy-middleware.
Simple Proxy Configuration (package.json)
For the majority of use cases, add a single line to your package.json:
{
"name": "my-app",
"proxy": "http://localhost:4000"
}
With this configuration, any request that the development server cannot resolve to a static asset—and that does not accept text/html—will be forwarded to http://localhost:4000. For example, a fetch('/api/users') from your React component will transparently reach http://localhost:4000/api/users.
Advanced Proxy Configuration (setupProxy.js)
When you need path rewriting, multiple targets, or WebSocket support, create src/setupProxy.js in your project root:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
// Proxy API requests to backend server
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
pathRewrite: {
'^/api': '' // Remove /api prefix before forwarding
},
onProxyReq: (proxyReq, req) => {
console.log(`Proxying ${req.method} ${req.path} to backend`);
}
})
);
// Proxy WebSocket connections
app.use(
'/socket.io',
createProxyMiddleware({
target: 'ws://localhost:6000',
ws: true,
changeOrigin: true
})
);
};
The development server automatically detects and loads this file without requiring any manual imports. This approach gives you full control over the http-proxy-middleware options, including custom headers, SSL certificate handling, and error callbacks.
Security Considerations
When configuring proxy settings for API requests, keep these security implications in mind:
- Never commit
DANGEROUSLY_DISABLE_HOST_CHECK=trueto version control. If you must disable host checking for remote development, place the variable in.env.development.local, which is ignored by Git by default. - Validate your target URLs in
setupProxy.jsto prevent accidental proxying to malicious hosts if environment variables are compromised. - Production builds ignore proxy settings—the
package.jsonproxy andsetupProxy.jsonly affectnpm start. Always configure your production server (NGINX, Apache, or Express) to handle API routing securely.
Summary
- Add a
proxystring topackage.jsonfor simple single-backend configurations—CRA handles the middleware automatically viaprepareProxyinWebpackDevServerUtils.js. - Create
src/setupProxy.jsfor complex scenarios requiring path rewriting, multiple targets, or WebSocket support usinghttp-proxy-middleware. - The proxy only operates during development (
npm start); production builds require server-side configuration. - Enabling a proxy activates strict host-header validation for security, which can only be disabled via
DANGEROUSLY_DISABLE_HOST_CHECK=truein.env.development.local.
Frequently Asked Questions
Can I use the proxy feature in production builds?
No. The proxy configuration in package.json and src/setupProxy.js is only used by the development server when you run npm start. In production, Create React App outputs static HTML, CSS, and JavaScript files. You must configure your production server (such as NGINX, Apache, or an Express server) to forward API requests to your backend.
Why am I getting CORS errors even with the proxy configured?
If you see CORS errors in the browser console, verify that your package.json proxy string starts with http:// or https://. The prepareProxy function in WebpackDevServerUtils.js automatically sets the changeOrigin option to true and rewrites the Origin header in the onProxyReq callback. If using src/setupProxy.js, ensure you include changeOrigin: true in your middleware configuration.
How do I proxy WebSocket connections in development?
To proxy WebSocket connections, use the src/setupProxy.js approach with the ws: true option. Pass ws: true to createProxyMiddleware for the specific path handling WebSocket traffic, and ensure your target URL uses the ws:// or wss:// protocol. The underlying http-proxy-middleware will upgrade the connection appropriately.
What happens if I specify both a package.json proxy and a setupProxy.js file?
If both configurations exist, src/setupProxy.js takes precedence. The development server checks for the existence of src/setupProxy.js and requires it if present, allowing you to override or extend the default proxy behavior. When using setupProxy.js, the proxy field in package.json is ignored, giving you full programmatic control over the proxy middleware configuration.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →