Preflight Checklist
Electron Version
43.0.0-nightly.20260413
What operating system(s) are you using?
Other Linux
Operating System Version
Reproduces on any host OS when installing an Electron binary for a different target OS via the postinstall script. Demonstrated here on Linux downloading a darwin / win32 build.
What arch are you using?
x64
Last Known Working Electron version
No response
Does the issue also appear in Chromium / Google Chrome?
No
Expected Behavior
ELECTRON_INSTALL_PLATFORM is documented in docs/tutorial/installation.md as the supported way to override the target platform for the Electron postinstall download. Setting it should make the postinstall script:
- Download the zip for the requested platform.
- Write
path.txt containing the executable path for that platform's build (electron.exe for win32, Electron.app/Contents/MacOS/Electron for darwin/mas, etc.).
- Produce an
isInstalled() result that reflects what is actually on disk, so subsequent installs don't re-download unnecessarily.
Actual Behavior
npm/install.js resolves the target platform in two places and the two disagree when ELECTRON_INSTALL_PLATFORM is used.
The download path, added in #49981, honors the new env var:
// npm/install.js, line ~20
const platform = process.env.ELECTRON_INSTALL_PLATFORM
|| process.env.npm_config_platform
|| process.platform;
But getPlatformPath(), which produces the executable path written to path.txt and compared during isInstalled(), was not updated:
// npm/install.js, line ~98
function getPlatformPath() {
const platform = process.env.npm_config_platform || os.platform();
...
}
Consequences on, for example, a Linux host running ELECTRON_INSTALL_PLATFORM=darwin npm install electron:
- The
darwin zip is downloaded and extracted to dist/ (correct).
path.txt is written as electron (the Linux executable name), not Electron.app/Contents/MacOS/Electron.
- On a subsequent install,
isInstalled() runs fs.existsSync(path.join(__dirname, 'dist', 'electron')), which does not exist in a darwin build, so the cache check fails and the zip is re-downloaded and re-extracted every time.
- Any tooling that reads
path.txt to locate the Electron executable will read the wrong filename for the artifact that was actually extracted.
Testcase Gist URL
No response
Additional Information
Minimal simulation of the branch taken by getPlatformPath():
// Simulating npm/install.js on a Linux host with ELECTRON_INSTALL_PLATFORM=darwin
process.env.ELECTRON_INSTALL_PLATFORM = 'darwin';
// Download resolution (after #49981): uses 'darwin' — downloads darwin zip
const downloadPlatform = process.env.ELECTRON_INSTALL_PLATFORM
|| process.env.npm_config_platform
|| process.platform; // 'darwin'
// path.txt resolution (getPlatformPath): ignores ELECTRON_INSTALL_PLATFORM
const pathTxtPlatform = process.env.npm_config_platform || require('os').platform();
// => 'linux' on Linux, so path.txt is written as 'electron' alongside a darwin build.
The fix is a one-liner in getPlatformPath() that brings it in line with the download resolution:
function getPlatformPath() {
- const platform = process.env.npm_config_platform || os.platform();
+ const platform = process.env.ELECTRON_INSTALL_PLATFORM || process.env.npm_config_platform || os.platform();
I will open a PR implementing this.
Preflight Checklist
Electron Version
43.0.0-nightly.20260413
What operating system(s) are you using?
Other Linux
Operating System Version
Reproduces on any host OS when installing an Electron binary for a different target OS via the postinstall script. Demonstrated here on Linux downloading a
darwin/win32build.What arch are you using?
x64
Last Known Working Electron version
No response
Does the issue also appear in Chromium / Google Chrome?
No
Expected Behavior
ELECTRON_INSTALL_PLATFORMis documented indocs/tutorial/installation.mdas the supported way to override the target platform for the Electron postinstall download. Setting it should make the postinstall script:path.txtcontaining the executable path for that platform's build (electron.exeforwin32,Electron.app/Contents/MacOS/Electronfordarwin/mas, etc.).isInstalled()result that reflects what is actually on disk, so subsequent installs don't re-download unnecessarily.Actual Behavior
npm/install.jsresolves the target platform in two places and the two disagree whenELECTRON_INSTALL_PLATFORMis used.The download path, added in #49981, honors the new env var:
But
getPlatformPath(), which produces the executable path written topath.txtand compared duringisInstalled(), was not updated:Consequences on, for example, a Linux host running
ELECTRON_INSTALL_PLATFORM=darwin npm install electron:darwinzip is downloaded and extracted todist/(correct).path.txtis written aselectron(the Linux executable name), notElectron.app/Contents/MacOS/Electron.isInstalled()runsfs.existsSync(path.join(__dirname, 'dist', 'electron')), which does not exist in adarwinbuild, so the cache check fails and the zip is re-downloaded and re-extracted every time.path.txtto locate the Electron executable will read the wrong filename for the artifact that was actually extracted.Testcase Gist URL
No response
Additional Information
Minimal simulation of the branch taken by
getPlatformPath():The fix is a one-liner in
getPlatformPath()that brings it in line with the download resolution:function getPlatformPath() { - const platform = process.env.npm_config_platform || os.platform(); + const platform = process.env.ELECTRON_INSTALL_PLATFORM || process.env.npm_config_platform || os.platform();I will open a PR implementing this.