# How to use proxies in Node.js with fetch, undici, axios and got

Node has no global proxy setting by default. Each client takes an agent or a dispatcher; once you know which one, the ProxShift URL does the rest.


## Built-in fetch and undici

Node's global `fetch` is undici. Give it a `ProxyAgent` per request with the `dispatcher` option, or set it globally once with `setGlobalDispatcher`.

```javascript
import { fetch, ProxyAgent, setGlobalDispatcher } from "undici";

const proxy = new ProxyAgent("http://USER-cc-us:PASS@res.proxshift.com:9000");

// Per request
const res = await fetch("https://api.ipify.org", { dispatcher: proxy });
console.log(await res.text());

// Or globally, for every fetch in the process
setGlobalDispatcher(proxy);
```

A `ProxyAgent` pools connections, so consecutive requests may reuse one connection and therefore one exit. For a fresh exit per request create the agent with `pipelining: 0` and `connections: 1`, or simply use a different `-sid-` per logical session.


## axios

axios's own `proxy` option does not tunnel HTTPS reliably; the standard approach is an agent from `https-proxy-agent` and `proxy: false`.

```javascript
import axios from "axios";
import { HttpsProxyAgent } from "https-proxy-agent";

const agent = new HttpsProxyAgent("http://USER-cc-de-city-berlin-sid-cart42-ttl-15m:PASS@res.proxshift.com:9000");
const client = axios.create({ httpsAgent: agent, httpAgent: agent, proxy: false, timeout: 30000 });

const { data } = await client.get("https://api.ipify.org");
console.log(data);
```


## got

```javascript
import got from "got";
import { HttpsProxyAgent } from "https-proxy-agent";

const agent = new HttpsProxyAgent("http://USER-cc-us:PASS@res.proxshift.com:9000");
const body = await got("https://api.ipify.org", { agent: { https: agent, http: agent }, timeout: { request: 30000 } }).text();
console.log(body);
```


## SOCKS5

```javascript
import { SocksProxyAgent } from "socks-proxy-agent";

// socks5h resolves the destination at the exit
const agent = new SocksProxyAgent("socks5h://USER-cc-us:PASS@res.proxshift.com:9001");
const res = await fetch("https://api.ipify.org", { dispatcher: undefined, agent }); // node-fetch style clients take `agent`
```

> Info: The built-in fetch does not accept `agent`; use undici's `ProxyAgent` for HTTP proxies, or a SOCKS-capable dispatcher such as `fetch-socks`. For most jobs the HTTP proxy on port 9000 is simpler.


## Environment variables

undici does not read `HTTPS_PROXY` by default. Recent undici versions ship `EnvHttpProxyAgent`, which does; set it as the global dispatcher and the whole process, including third-party libraries built on fetch, goes through the proxy.

```javascript
import { EnvHttpProxyAgent, setGlobalDispatcher } from "undici";
// HTTPS_PROXY=http://USER-cc-us:PASS@res.proxshift.com:9000 NO_PROXY=localhost node app.js
setGlobalDispatcher(new EnvHttpProxyAgent());
```


## Concurrency and rotation

- One `ProxyAgent` per sticky session (different `-sid-`), shared by all requests of that session.
- For wide rotation, keep one agent but disable connection reuse, or run N agents with N session ids and round-robin them.
- Watch `UND_ERR_SOCKET` and `ECONNRESET`: a residential exit went away; retry once, the next connection picks another.


## Questions

**Why does axios ignore my proxy for HTTPS?**

Its built-in proxy support is limited for CONNECT tunnels. Use https-proxy-agent as httpsAgent and set proxy: false so axios does not try to handle it itself.

**Can I proxy only some requests?**

Yes. Pass the dispatcher or agent on the requests that need it and leave the others untouched; nothing is global unless you call setGlobalDispatcher.

Source: https://proxshift.com/guides/nodejs-fetch-undici-axios
