-
Notifications
You must be signed in to change notification settings - Fork 4
Using a proxy
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.
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.
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:
-
--agent <path>CLI flag — direct path, wins over everything else. -
--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. -
DOWNLOAD_AGENTenvironment 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
installscript invokesinstall-from-cache, prefer passing--agent-var YOURPACKAGE_DOWNLOAD_AGENTso consumers of your library can configure a proxy that applies only to your package, without affecting other addons that also useinstall-artifact-from-github. This mirrors how the existing--host-var/--skip-path-var/--skip-ver-varflags namespaceDOWNLOAD_HOST/DOWNLOAD_SKIP_PATH/DOWNLOAD_SKIP_VER. See theinstall-from-cachereference for the full set of*-varflags.
DOWNLOAD_AGENT=./proxy-agent.js npm installIn 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.
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();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.
{
"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."
See "Quick start" above. Reads env vars, picks protocol automatically, supports PAC.
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 forundici.fetch()andundici.request(). They implement theDispatcherinterface, not the legacyhttp.Agentinterface thatinstall-from-cacheuses. Confirm compatibility for your Node version before relying on this.
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'
});The path can be supplied three ways. Earlier wins.
"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.
"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 installProject-specific names prevent collisions when several addons coexist in the same node_modules.
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.
- "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 vianpm 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-cachemakes both HTTPS (the GitHub default) and HTTP requests (whenDOWNLOAD_HOSToverrides to plain HTTP). The agent must handle whichever scheme your downloads use.proxy-agentandEnvHttpProxyAgenthandle both;https-proxy-agenthandles HTTPS only;http-proxy-agenthandles HTTP only. -
CONNECT auth. Most agents accept credentials via the URL:
http://user:pass@proxy.corp:8080. Embed them inHTTPS_PROXYand the agent forwardsProxy-Authorizationautomatically. -
Self-signed certs on the proxy. Set
NODE_EXTRA_CA_CERTS=/path/to/ca-bundle.pemin your environment. This is a Node-level setting and applies regardless of which agent you use.
-
Install-from-cache — the
install-from-cachereference, including all environment variables. -
Making a local mirror — alternative for environments where outbound traffic to
github.comis blocked entirely.