Skip to content

Using a proxy

Eugene Lazutkin edited this page Apr 26, 2026 · 2 revisions

Some users — typically in corporate / enterprise environments — sit behind an HTTP, HTTPS, or SOCKS proxy and need install-from-cache to route asset downloads through it. This page explains how.

Why opt-in?

This package has a strict zero-runtime-dependency policy. Every npm install of every consumer (currently >1M/week for node-re2 alone) downloads exactly: bin/, package.json, README.md, LICENSE. Nothing else. Bundling a proxy package would force a 25-package transitive tree on the 99% of users who don't need a proxy, just to serve the 1% who do.

So the rule is simple: you bring your own agent. This package keeps zero deps; you pick whichever proxy package fits your environment, install it in your own project, and tell us where to find it.

How it works

Point install-from-cache at a JavaScript module whose default export is an http.Agent instance (or anything compatible with the agent option of http.request). The bin dynamically import()s the module and uses that default export as the agent for every download.

There are three ways to specify the path, in order of precedence:

  1. --agent <path> CLI flag — direct path, wins over everything else.
  2. --agent-var <ENVVAR> CLI flag — name of an environment variable to read the path from. Used by libraries that want a project-specific env var (e.g. RE2_DOWNLOAD_AGENT) so multiple addons in the same environment don't collide.
  3. DOWNLOAD_AGENT environment variable — the default fallback, used if neither flag is set.

If none of these resolve to a path, nothing changes — connections are direct, exactly like before.

If a path is specified but the module fails to load (typo, missing dep, syntax error), install-from-cache prints a warning to stderr and falls back to direct connections. It does not abort. This is by design: a misconfigured proxy shouldn't break installs that would otherwise succeed.

Library authors: if your package's install script invokes install-from-cache, prefer passing --agent-var YOURPACKAGE_DOWNLOAD_AGENT so consumers of your library can configure a proxy that applies only to your package, without affecting other addons that also use install-artifact-from-github. This mirrors how the existing --host-var / --skip-path-var / --skip-ver-var flags namespace DOWNLOAD_HOST / DOWNLOAD_SKIP_PATH / DOWNLOAD_SKIP_VER. See the install-from-cache reference for the full set of *-var flags.

Quick start

For end users (one-off install)

DOWNLOAD_AGENT=./proxy-agent.js npm install

For library authors (recommended)

In your library's package.json, namespace the env var so consumers don't have to opt into a global DOWNLOAD_AGENT that affects every other addon on their machine:

{
  "scripts": {
    "install": "install-from-cache --artifact build/Release/your-addon.node --agent-var YOURPKG_DOWNLOAD_AGENT"
  }
}

Now consumers run:

YOURPKG_DOWNLOAD_AGENT=./proxy-agent.js npm install your-pkg

…and the proxy applies only to your package. This matches the existing convention for --host-var / --skip-path-var / --skip-ver-var.

The agent thunk

Whichever flag the project uses, the module it points at looks the same. For proxy-agent:

// proxy-agent.js (in the consumer's project)
import {ProxyAgent} from 'proxy-agent';
export default new ProxyAgent();

The consumer adds proxy-agent (or whichever package they prefer) to their own package.json dependencies. install-artifact-from-github itself stays zero-dep.

If the consumer's project is CommonJS, use .cjs:

// proxy-agent.cjs
const {ProxyAgent} = require('proxy-agent');
module.exports = new ProxyAgent();

Selecting a proxy package

Most users do not need the full proxy-agent. Here are the realistic choices:

Package Weekly downloads Transitive deps Covers When to choose
proxy-agent ~27M ~25 HTTP, HTTPS-CONNECT, SOCKS, PAC scripts You don't know which protocol the proxy uses, or your environment uses PAC scripts
https-proxy-agent ~163M 2 HTTPS through HTTP CONNECT The 95% case: your corporate proxy is http://proxy.corp:8080 and you're downloading from https://github.com
http-proxy-agent ~114M 2 HTTP through HTTP proxy You're using DOWNLOAD_HOST over plain HTTP through a proxy (rare)
socks-proxy-agent high small SOCKS4/5 You explicitly need SOCKS
undici EnvHttpProxyAgent bundled with Node 18+ 0 (built-in) HTTPS-CONNECT with env-var routing You want zero deps; Node already ships undici

All four *-proxy-agent packages share the same author (Nathan Rajlich, also author of node-gyp) and live in the TooTallNate/proxy-agents monorepo.

Default recommendation: https-proxy-agent if you know your corporate proxy is HTTP-CONNECT (it almost certainly is). Smaller, faster install, fewer transitive deps to audit.

Examples

https-proxy-agent (lightest, recommended)

{
  "dependencies": {
    "https-proxy-agent": "^9"
  }
}
// proxy-agent.js
import {HttpsProxyAgent} from 'https-proxy-agent';
const proxyUrl = process.env.HTTPS_PROXY || process.env.https_proxy;
export default proxyUrl ? new HttpsProxyAgent(proxyUrl) : false;

Note that https-proxy-agent does not read env vars itself — you wire that up in the thunk. The false fallback means "no proxy, use the default agent."

proxy-agent (kitchen sink)

See "Quick start" above. Reads env vars, picks protocol automatically, supports PAC.

undici.EnvHttpProxyAgent (zero external deps)

Available in Node 18+ via the bundled undici. Reads HTTP_PROXY / HTTPS_PROXY / NO_PROXY automatically.

// proxy-agent.js
import {EnvHttpProxyAgent} from 'undici';
export default new EnvHttpProxyAgent();

Caveat: undici's agents are designed for undici.fetch() and undici.request(). They implement the Dispatcher interface, not the legacy http.Agent interface that install-from-cache uses. Confirm compatibility for your Node version before relying on this.

A custom / internal agent

If your organization has its own proxy package, just default-export an instance:

// proxy-agent.js
import {OurInternalAgent} from '@acme/proxy';
export default new OurInternalAgent({
  proxy: process.env.ACME_PROXY,
  trust: '/etc/acme/ca-bundle.pem'
});

Configuring the agent path

The path can be supplied three ways. Earlier wins.

1. --agent <path> CLI flag

"install": "install-from-cache --artifact build/Release/foo.node --agent ./proxy-agent.js"

Hard-codes the path in the project. Useful when the proxy thunk is checked into the consuming repo and shouldn't be configurable per-environment.

2. --agent-var <ENVVAR> CLI flag (recommended for libraries)

"install": "install-from-cache --artifact build/Release/foo.node --agent-var RE2_DOWNLOAD_AGENT"

The library declares the env-var name; consumers set the var:

RE2_DOWNLOAD_AGENT=./re2-proxy.js npm install

Project-specific names prevent collisions when several addons coexist in the same node_modules.

3. DOWNLOAD_AGENT environment variable (default fallback)

export DOWNLOAD_AGENT="$HOME/proxy-agent.js"

Applies to every project on the machine that uses install-from-cache and doesn't override the env-var name. Best for personal developer setups when the same proxy applies to everything.

Troubleshooting

  • "Failed to load download agent" — the path is wrong, the file has a syntax error, or a package referenced inside it isn't installed. Check the stderr message; the install will continue without a proxy.
  • Module path resolution. Path inputs (CLI or env) accept a filesystem path (relative or absolute). Resolved against process.cwd() (which is your project root when invoked via npm install). For a bare package name, prefix with ./node_modules/<name>/... or write a local thunk that imports it.
  • The agent doesn't support HTTPS. install-from-cache makes both HTTPS (the GitHub default) and HTTP requests (when DOWNLOAD_HOST overrides to plain HTTP). The agent must handle whichever scheme your downloads use. proxy-agent and EnvHttpProxyAgent handle both; https-proxy-agent handles HTTPS only; http-proxy-agent handles HTTP only.
  • CONNECT auth. Most agents accept credentials via the URL: http://user:pass@proxy.corp:8080. Embed them in HTTPS_PROXY and the agent forwards Proxy-Authorization automatically.
  • Self-signed certs on the proxy. Set NODE_EXTRA_CA_CERTS=/path/to/ca-bundle.pem in your environment. This is a Node-level setting and applies regardless of which agent you use.

See also

  • Install-from-cache — the install-from-cache reference, including all environment variables.
  • Making a local mirror — alternative for environments where outbound traffic to github.com is blocked entirely.

Clone this wiki locally