Skip to content

install‐from‐cache

Eugene Lazutkin edited this page Jul 8, 2026 · 1 revision

install-from-cache retrieves a previously saved artifact, optionally verifies its integrity, tests if it works properly, and rebuilds a project from sources in the case of failure.

How to use

In your package.json (pseudo-code with comments):

{
  // your custom package.json stuff
  // ...
  "scripts": {
    // your scripts go here
    // ...

    // saves an artifact
    "save-to-github": "save-to-github-cache --artifact build/Release/ABC.node",

    // installs using pre-created artifacts
    "install": "install-from-cache --artifact build/Release/ABC.node",

    // used by "install" to test the artifact
    "verify-build": "node scripts/verify-build.js"

    // used by "install" to rebuild from sources
    "rebuild": "node-gyp rebuild"
  }
}

When a project, which uses install-artifact-from-github, is being installed, it does the following actions:

  • Acquiring an artifact from the cache (an appropriate GitHub release).
    1. If the environment variable DEVELOPMENT_SKIP_GETTING_ASSET is set to a non-empty value ⇒ it builds from sources.
    2. If the file .development is present in the project folder ⇒ it builds from sources.
    3. (Since 1.7.0) If a forced build is requested (--force-build, or DOWNLOAD_FORCE_BUILD / --force-build-var) ⇒ it builds from sources.
    4. It tries to download an appropriate artifact compressed by brotli, then gzip, then uncompressed.
    5. (Since 1.7.0) If the artifact was downloaded and the addon pins an artifactHashes bag in its package.json, its SHA-256 is checked against the bag entry for this platform before it is written; a mismatch — or a slot the bag does not cover — ⇒ it builds from sources. Only the canonical GitHub source is checked; a mirror (--host / DOWNLOAD_HOST) is never checked. See Verifying artifacts.
    6. If it works ⇒ done. If all downloads (or the integrity check) failed ⇒ it builds from sources.
  • In order to check that the downloaded artifact works:
    • It runs npm run verify-build. You may provide the script verify-build to do the checking.
      • If it returns with 0 exit code, we are done. Otherwise ⇒ it builds from sources.
    • If there is no verify-build, it tries npm test.
      • If it returns with 0 exit code, we are done. Otherwise ⇒ it builds from sources.
    • If both scripts are missing ⇒ it builds from sources.
  • If it was determined to build the artifact from sources, it runs npm run rebuild, which should be provided.

Environment variables

  • DEVELOPMENT_SKIP_GETTING_ASSET — if it is set to a non-empty value, it forces the build from sources. It is useful for development and testing.
  • DEVELOPMENT_SHOW_VERIFICATION_RESULTS — if it is non-empty, it shows the verification output. Otherwise, the output is suppressed to avoid scaring unsuspecting users with possible errors. It is useful for development and testing.
  • DOWNLOAD_HOST — if set, its value is used instead of https://github.com.
  • (Since 1.3.0) DOWNLOAD_SKIP_PATH — if set to a non-empty value, it allows to skip a project-specific part of path. See below for more details.
  • (Since 1.3.0) DOWNLOAD_SKIP_VER — if set to a non-empty value, it allows to skip a version-specific part of path. See below for more details.
  • (Since 1.5.0) DOWNLOAD_AGENT — path to a JS module whose default export is an http.Agent instance. Used as the agent option for every download. Useful for routing through corporate HTTP/HTTPS/SOCKS proxies. The variable name can be overridden with --agent-var (see below) for project-specific isolation. See Using a proxy for details and examples.
  • (Since 1.6.0) DOWNLOAD_NAPI — if set to an integer N-API level, the URL slot that normally encodes the Node ABI is replaced with napi-v${level}. Equivalent to --napi; the variable name can be overridden with --napi-var. See Using N-API.
  • (Since 1.7.0) DOWNLOAD_FORCE_BUILD — if set to a non-empty value, the download is skipped entirely and the project is built from sources. A clearly-named alias for DEVELOPMENT_SKIP_GETTING_ASSET; equivalent to --force-build, and the variable name can be overridden with --force-build-var.
  • (Since 1.7.0) GITHUB_SERVER_URL — the canonical GitHub host used for the default (integrity-verified) download; defaults to https://github.com. GitHub Actions sets it automatically, and GitHub Enterprise can point the verified download at its own instance. Unlike DOWNLOAD_HOST, a GITHUB_SERVER_URL source is still integrity-checked. See Verifying artifacts.

This script is meant to be run using npm run. It relies on npm environment variables to learn about the project.

Command-line parameters

  • --artifact path — points to the location of the downloaded artifact. It is a required parameter.
  • --prefix prefix — provides a prefix for the generated artifact name. Default: ''.
  • --suffix suffix — provides a suffix for the generated artifact name. Default: ''.
  • --host host — provides a prefix for the download host. It should not end with /. Example: --host https://sample.com/repo.
    • If specified and non-empty, its value sets the host with an optional path prefix.
    • The default: https://github.com.
  • --host-var ENVVAR — provides the name of an environment variable, which value will specify the download host. Example: --host-var RE2_DOWNLOAD_MIRROR.
    • Used only if --host is not specified.
    • If it is not specified, DOWNLOAD_HOST name is assumed.
    • If the specified environment variable is empty, https://github.com will be used.
  • --skip-path — if present, allows skipping a project-specific part of the path.
    • If present, a project-specific part of the path. See below for more details.
    • The default: don't skip.
  • --skip-path-var ENVVAR — provides the name of an environment variable, which value will specify if a project-specific part of the path should be skipped. Example: --skip-path-var RE2_SKIP_PATH.
    • Used only if --skip-path is not specified.
    • If it is not specified, DOWNLOAD_SKIP_PATH name is assumed.
    • If the specified environment variable is non-empty, a project-specific part of the path should be skipped.
  • --skip-ver — if present, allows skipping a version-specific part of the path.
    • If present, a version-specific part of the path. See below for more details.
    • The default: don't skip.
  • --skip-ver-var ENVVAR — provides the name of an environment variable, which value will specify if a version-specific part of the path should be skipped. Example: --skip-ver-var RE2_SKIP_VER.
    • Used only if --skip-ver is not specified.
    • If it is not specified, DOWNLOAD_SKIP_VER name is assumed.
    • If the specified environment variable is non-empty, a version-specific part of the path should be skipped.
  • (Since 1.5.0) --agent module-path — path to a JS module whose default export is an http.Agent instance. Used as the agent option for every HTTP(S) download. Resolved relative to process.cwd().
    • If specified and non-empty, its value wins over any --agent-var env var.
  • (Since 1.5.0) --agent-var ENVVAR — provides the name of an environment variable whose value will specify the agent module path. Example: --agent-var RE2_DOWNLOAD_AGENT.
    • Used only if --agent is not specified.
    • If it is not specified, DOWNLOAD_AGENT name is assumed.
    • If the specified environment variable is empty, no agent is used (default behavior).
    • See Using a proxy for end-to-end examples.
  • (Since 1.6.0) --napi level — declare the N-API version this addon's binary targets. When set, the URL slot that normally encodes the Node ABI (process.versions.modules) is replaced with napi-v${level}. Example: --napi 8 produces asset names like ${prefix}linux-x64-napi-v8${suffix}.
  • (Since 1.6.0) --napi-var ENVVAR — provides the name of an environment variable whose value will specify the N-API level. Example: --napi-var RE2_NAPI.
    • Used only if --napi is not specified.
    • If it is not specified, DOWNLOAD_NAPI name is assumed.
    • If the specified environment variable is empty, the legacy ABI slot is used.
    • See Using N-API for the full picture and runtime support matrix.
  • (Since 1.7.0) --force-build — skip the prebuilt download entirely and go straight to npm run rebuild. Nothing is fetched or verified; trust collapses to npm plus your own toolchain. A clearly-named alias for the DEVELOPMENT_SKIP_GETTING_ASSET / .development short-circuit.
  • (Since 1.7.0) --force-build-var ENVVAR — provides the name of an environment variable whose non-empty value forces the source build.
    • Used only if --force-build is not specified.
    • If it is not specified, DOWNLOAD_FORCE_BUILD name is assumed.

Ultimately, the downloadable file name has the following format:

`${host}/${user}/${repo}/releases/download/${tag}/${prefix}${platform}-${arch}-${abiSlot}${suffix}${compression}`

The abiSlot is either napi-v${level} (since 1.6.0, when --napi/DOWNLOAD_NAPI is set) or the legacy Node ABI from process.versions.modules.

Where:

  • host is a hostname with an optional path prefix. See above --host and --host-var for more details.
  • user is a repository user name. It is deduced from package.json.
  • repo is a repository name. It is deduced from package.json.
  • tag is a tag that triggered the build. It is deduced from package.json.
  • prefix is a user-supplied value (see above).
  • platform is based on process.platform.
    • Because Linux has different implementations of the C standard library, a special case is made for musl used by distributions like Alpine. Such platforms have a code linux-musl.
  • arch is based on process.arch.
  • abi is based on process.versions.modules.
  • suffix is a user-supplied value (see above).
  • compression can be .br, .gz or an empty string (since 1.4.0) if no compression was applied.

Since 1.3.1: platform, arch and abi can be manually overridden for cross-platform builds. It allows specifying a different pre-compiled module to be fetched. In this case, no build verification is done. See "Recognized NPM parameters" below to learn how to override platform-specific parameters.

Example with default values: https://github.com/uhop/node-re2/releases/download/1.15.2/linux-x64-83.br.

If --skip-path is specified or --skip-path-var environment variable values is non-empty the following part of the path will be skipped:

`/${user}/${repo}/releases/download`

If --skip-ver is specified or --skip-ver-var environment variable values is non-empty the following part of the path will be skipped:

`/${tag}`

Both those variables are used mostly to organize local mirrors.

The former example with DOWNLOAD_HOST=https://local.mirror, DOWNLOAD_SKIP_PATH=1, DOWNLOAD_SKIP_VER=1: https://local.mirror/linux-x64-83.br.

Recognized NPM parameters

Some parameters can be specified when using NPM like this:

npm install re2 --platform=linux

The full list of such parameters:

  • Since 1.3.1: Parameters used to specify platform-specific values for cross-platform builds to specify manually what pre-compiled binary to fetch:
    • --platform=XXX — platform value such as darwin, win32, linux, linux-musl. The default is the current platform based on process.platform.
    • --platform-arch=XXX — platform CPU architecture such as x64. The default is the current CPU architecture based on process.arch.
    • --platform-abi=XXX — platform ABI version such as 108. The default is the ABI of the currently running Node based on process.versions.modules.

Example

The realistic complex example can be found in uhop/node-re2:

Notes

NPM 12

Starting with npm 12 (July 2026), npm does not run dependency lifecycle scripts by default. install-from-cache runs as the consuming package's install script, so end users must approve that package once (npm approve-scripts <addon>) — otherwise neither the prebuilt download nor the node-gyp fallback runs. See NPM 12 and install scripts for the consumer flow and author guidance.

What builds are available?

It can be checked on GitHub using a URL like this:

https://github.com/uhop/node-re2/releases/tag/TAG

Where TAG is a version name. Example: https://github.com/uhop/node-re2/releases/tag/1.17.6

NPM 7

Update on 11/12/2020: npm 7 has changed completely what data it exposes through environment variables. Instead, it provides a path to package.json. Arguably it is a less messy alternative. Support for npm 7 is implemented starting with version 1.15.9. Previous versions fail gracefully and build locally.

Fixed in NPM 7

These notes are kept here for posterity:

  • Unfortunately, NPM 7 introduced an error: npm ci does not build a binary extension. If you encountered this problem, please use npm i instead. The bug was filed with NPM: https://github.com/npm/cli/issues/2169

Yarn & PNPM

Both those package managers were confused by the npm 7 change and removed too much variables. Bugs were filed with them and fixed.

Clone this wiki locally