Skip to main content

proxy-agent vs global-agent vs hpagent: HTTP Proxy Agents in Node.js (2026)

·PkgPulse Team

TL;DR

proxy-agent maps proxy URIs to the correct agent implementation — auto-selects HTTP, HTTPS, SOCKS4/5 agents based on the proxy URL protocol, used by npm, yarn, and many CLI tools. global-agent bootstraps a global HTTP/HTTPS agent that routes all requests through a proxy — set GLOBAL_AGENT_HTTP_PROXY and every http.request uses it automatically. hpagent is the modern HTTP/HTTPS proxy agent — supports keep-alive connections through HTTPS proxies, handles CONNECT tunneling correctly, minimal and focused. In 2026: proxy-agent for multi-protocol proxy support, global-agent for transparent global proxying, hpagent for reliable HTTPS-over-HTTPS proxy connections.

Key Takeaways

  • proxy-agent: ~10M weekly downloads — auto-selects agent by proxy URL protocol
  • global-agent: ~5M weekly downloads — patches Node.js globals, all requests proxied
  • hpagent: ~3M weekly downloads — HTTPS proxy with keep-alive, CONNECT tunneling
  • Corporate environments often require HTTP proxies — these libraries make it work
  • HTTP_PROXY / HTTPS_PROXY env vars are the standard — libraries read them
  • Node.js has no built-in proxy support — you need an agent library

The Problem

Node.js HTTP requests don't support proxies natively:

  fetch("https://api.example.com")
  // → Direct connection (no proxy)

  // But behind a corporate firewall:
  // → Connection refused / timeout

Corporate networks require:
  HTTP_PROXY=http://proxy.corp.com:8080
  HTTPS_PROXY=http://proxy.corp.com:8080
  NO_PROXY=localhost,127.0.0.1,.internal.com

  // Node.js ignores these env vars by default
  // You need a proxy agent library

proxy-agent

proxy-agent — smart proxy selection:

Basic usage

import { ProxyAgent } from "proxy-agent"

// Auto-detects proxy from environment variables:
const agent = new ProxyAgent()

// Uses HTTP_PROXY, HTTPS_PROXY, NO_PROXY automatically:
const response = await fetch("https://api.example.com", {
  agent,  // Routes through proxy if env vars are set
})

// Or specify proxy explicitly:
const agent2 = new ProxyAgent("http://proxy.corp.com:8080")

Multi-protocol support

import { ProxyAgent } from "proxy-agent"

// HTTP proxy:
new ProxyAgent("http://proxy.corp.com:8080")

// HTTPS proxy:
new ProxyAgent("https://secure-proxy.corp.com:443")

// SOCKS5 proxy:
new ProxyAgent("socks5://socks-proxy.corp.com:1080")

// SOCKS4 proxy:
new ProxyAgent("socks4://socks-proxy.corp.com:1080")

// PAC file (Proxy Auto-Config):
new ProxyAgent("pac+https://corp.com/proxy.pac")

// Auto-selects the right agent implementation based on protocol

With HTTP clients

import { ProxyAgent } from "proxy-agent"
import https from "node:https"

const agent = new ProxyAgent()

// With node:https:
https.get("https://api.example.com", { agent }, (res) => {
  // Response through proxy
})

// With fetch (Node.js 18+):
const response = await fetch("https://api.example.com", {
  dispatcher: agent,  // undici dispatcher
})

// With got:
import got from "got"
const data = await got("https://api.example.com", {
  agent: { https: agent },
}).json()

NO_PROXY support

import { ProxyAgent } from "proxy-agent"

// Respects NO_PROXY environment variable:
// NO_PROXY=localhost,127.0.0.1,.internal.com,*.corp.net

const agent = new ProxyAgent()

// These skip the proxy:
fetch("http://localhost:3000", { agent })          // Direct
fetch("https://api.internal.com", { agent })       // Direct
fetch("https://service.corp.net", { agent })       // Direct

// These use the proxy:
fetch("https://api.github.com", { agent })         // Proxied
fetch("https://registry.npmjs.org", { agent })     // Proxied

global-agent

global-agent — transparent global proxy:

Bootstrap

import { bootstrap } from "global-agent"

// Patches Node.js HTTP/HTTPS globals:
bootstrap()

// Now ALL http/https requests use the proxy:
// Reads GLOBAL_AGENT_HTTP_PROXY or HTTP_PROXY

// Every request is now proxied — no agent parameter needed:
const response = await fetch("https://api.example.com")
// → Automatically routes through proxy

Environment variables

# Set proxy via environment variables:
export GLOBAL_AGENT_HTTP_PROXY=http://proxy.corp.com:8080
export GLOBAL_AGENT_HTTPS_PROXY=http://proxy.corp.com:8080
export GLOBAL_AGENT_NO_PROXY=localhost,127.0.0.1

# Or use standard HTTP_PROXY (global-agent reads both):
export HTTP_PROXY=http://proxy.corp.com:8080
export HTTPS_PROXY=http://proxy.corp.com:8080
export NO_PROXY=localhost,127.0.0.1

# Run your app:
node app.js
# All HTTP/HTTPS requests now use the proxy

Programmatic configuration

import { bootstrap } from "global-agent"

bootstrap()

// Configure at runtime:
global.GLOBAL_AGENT.HTTP_PROXY = "http://proxy.corp.com:8080"
global.GLOBAL_AGENT.HTTPS_PROXY = "http://proxy.corp.com:8080"
global.GLOBAL_AGENT.NO_PROXY = "localhost,127.0.0.1"

// Disable for specific requests by passing agent: false
// (implementation depends on the HTTP client)

Use case: CLI tools

// Perfect for CLI tools that need corporate proxy support:
#!/usr/bin/env node
import { bootstrap } from "global-agent"

// Bootstrap before any HTTP requests:
bootstrap()

// Now all npm registry requests, API calls, etc. use proxy:
import { fetchPackageInfo } from "./api.js"
const info = await fetchPackageInfo("react")

hpagent

hpagent — modern HTTPS proxy agent:

Basic usage

import { HttpsProxyAgent } from "hpagent"

const agent = new HttpsProxyAgent({
  proxy: "http://proxy.corp.com:8080",
  keepAlive: true,        // Reuse proxy connections
  keepAliveMsecs: 1000,
  maxSockets: 256,
  maxFreeSockets: 256,
})

// Use with https:
import https from "node:https"
https.get("https://api.example.com", { agent }, (res) => {
  // Response tunneled through proxy
})

HTTP and HTTPS agents

import { HttpProxyAgent, HttpsProxyAgent } from "hpagent"

// For HTTP targets (http://...):
const httpAgent = new HttpProxyAgent({
  proxy: "http://proxy.corp.com:8080",
  keepAlive: true,
})

// For HTTPS targets (https://...):
const httpsAgent = new HttpsProxyAgent({
  proxy: "http://proxy.corp.com:8080",
  keepAlive: true,
})

// With got:
import got from "got"
const data = await got("https://api.example.com", {
  agent: {
    http: httpAgent,
    https: httpsAgent,
  },
}).json()

Why hpagent over alternatives

hpagent advantages:
  ✅ Correct HTTPS-over-HTTPS (CONNECT tunneling)
  ✅ Keep-alive through proxy connections
  ✅ Compatible with Node.js http.Agent API
  ✅ Minimal — focused on HTTP/HTTPS proxies
  ✅ Used by Elastic (elasticsearch-js)

  vs proxy-agent:
    ❌ No SOCKS support
    ❌ No PAC file support
    ❌ No auto-detection from env vars
    ✅ Simpler, more focused
    ✅ Better keep-alive handling

  vs global-agent:
    ❌ Not transparent — must pass agent explicitly
    ✅ More control per-request
    ✅ No global monkey-patching

Feature Comparison

Featureproxy-agentglobal-agenthpagent
HTTP proxy
HTTPS proxy
SOCKS4/5
PAC files
Auto env vars❌ (manual)
Global patching
Keep-alive✅ (better)
NO_PROXY❌ (manual)
Per-request❌ (global)
DependenciesMany (agents)Few0
Weekly downloads~10M~5M~3M

When to Use Each

Use proxy-agent if:

  • Need multi-protocol proxy support (HTTP, HTTPS, SOCKS, PAC)
  • Building a CLI tool that should work behind any proxy type
  • Want automatic environment variable detection
  • npm/yarn use this — battle-tested in package managers

Use global-agent if:

  • Want transparent proxying without changing every HTTP call
  • Building an app where ALL requests should go through a proxy
  • Corporate environment — bootstrap once, everything works
  • Don't want to pass agent to every HTTP client

Use hpagent if:

  • Need reliable keep-alive connections through HTTPS proxies
  • Want explicit per-request proxy control (not global)
  • Using Elasticsearch, Fastify, or similar clients that accept agents
  • Only need HTTP/HTTPS proxy (no SOCKS/PAC)

Methodology

Download data from npm registry (weekly average, February 2026). Feature comparison based on proxy-agent v6.x, global-agent v3.x, and hpagent v1.x.

Compare HTTP networking and developer tooling on PkgPulse →

Comments

Stay Updated

Get the latest package insights, npm trends, and tooling tips delivered to your inbox.