Electron runtime alignment

Updated Jul 27, 2026

When upgrading Electron, keep runtime and native-module rebuild settings aligned in the same change:

  • Update devDependencies.electron in package.json.
  • Align @types/node in package.json to the bundled Node.js major for the target Electron release.
  • Bump the fallback target version in bin/rebuild-node-pty.cjs.
  • Adjust app/package.json if runtime dependencies (for example, node-pty) need a compatibility bump for the new Electron Application Binary Interface (ABI).
  • If CI rebuilds native modules, align .github/workflows/nodejs.yml NODE_VERSION and any architecture-specific Node bootstrap downloads to the same Node.js major family.
  • Run bun install to validate snapshot generation, install-app-deps, and node-pty rebuilding before running the remaining gates.
  • The installation pipeline intentionally invokes node bin/copy-node-modules.mjs during postinstall. Bun remains the default runner elsewhere, but Node's native copy path is currently the stable option for mirroring large node_modules trees on Linux/Windows Subsystem for Linux (WSL) after install-app-deps.

Current repository runtime baseline after roadmap item 1.4.13:

  • electron and electron-mksnapshot: ^40.2.1
  • @types/node: ^24.10.12
  • CI workflow NODE_VERSION: 24.11.1

CI Python/node-gyp baseline after roadmap item 1.4.15 macOS scope:

  • In CI jobs that prepare native-module builds, create a per-job Python virtual environment for node-gyp bootstrap packages instead of running system-level pip install.
  • Install pip, packaging, and setuptools inside that virtual environment, then set PYTHON and npm_config_python to the virtual-environment interpreter path for the install/rebuild steps that need node-gyp.
  • Keep npm_config_node_gyp aligned to the workspace node-gyp entrypoint in the same job, so Python and node-gyp resolution stay deterministic.
  • Run this isolated Python bootstrap before bun install; this keeps hosted macOS lanes compliant with Python Enhancement Proposal (PEP) 668 (externally-managed-environment) and avoids host-level Python mutation.

Linux runtime reliability baseline after roadmap item 1.4.15 Linux scope:

  • Linux ARM CI coverage is Linux aarch64 only; do not reintroduce armv7 (armv7l) lanes or release artefact targets.
  • Prefer native ARM runners for Linux aarch64 CI lanes instead of emulated copy-to-image flows, which previously failed with disk-exhaustion errors.
  • Keep Linux dependency installation shared via .github/actions/install-linux-e2e-runtime-deps/action.yml so fast-lane and deep-lane jobs stay in sync.
  • Before running bun install on Linux aarch64 CI lanes, provision qemu-x86_64-static, add the amd64 dpkg architecture, and install the required x86_64 runtime libraries (libc6, libstdc++6, libgcc-s1, libglib2.0-0, libexpat1, and libpcre2-8-0) so Electron's x64 mksnapshot and v8_context_snapshot_generator binaries can run.
  • On Ubuntu arm runners that default to ports.ubuntu.com, use explicit apt source entries (ports for arm64 and archive.ubuntu.com plus security.ubuntu.com for amd64) before installing :amd64 packages. Otherwise, apt tries to resolve amd64 indexes from ports and fails with 404 Not Found. Keep this source pinning for all later apt invocations in the same job after adding amd64; the Linux dependency installation action now applies it automatically when it detects an Ubuntu arm64 host with amd64 multiarch enabled.
  • The shared Linux dependency installation action resolves the Advanced Linux Sound Architecture (ALSA) runtime package by availability (libasound2t64 on newer Ubuntu releases, libasound2 on Ubuntu 22.04) so the same workflow configuration works across Jammy and Noble runners.
  • After provisioning amd64 runtime packages on Linux aarch64 CI lanes, export QEMU_LD_PREFIX=/ so Quick Emulator (QEMU) resolves x86_64 shared libraries from the host multiarch rootfs.
  • For Linux aarch64 CI lanes, set SKIP_V8_SNAPSHOT=1 during bun install so snapshot generation cannot stall install for hours under emulation.
  • For Linux aarch64 CI lanes, set SKIP_NODE_PTY_REBUILD=1 during bun install so the lane does not hang in long-running node-gyp Electron header extraction for node-pty; keep npm_config_node_gyp and Python toolchain wiring in place for the remaining native-module install steps.
  • When Linux aarch64 CI lanes package artefacts after install-time snapshot skipping, set SKIP_V8_SNAPSHOT_COPY=1 for the packaging step, so CI uses Electron's default snapshots instead of waiting on arm64 custom snapshot generation that can stall under QEMU.
  • For local Linux aarch64 validation where snapshots are still required, set SKIP_X64_V8_SNAPSHOT=1 to avoid generating the additional x64 snapshot pass under QEMU.
  • For Linux aarch64 native-module rebuild reliability, run bun install before other gates and keep npm_config_node_gyp pointed at the workspace node-gyp entrypoint in CI jobs that rebuild native modules.

Windows runtime reliability baseline after roadmap item 1.4.15 Windows scope:

  • Keep Windows CI on windows-2022 (x64) in the shared build matrix and run Windows install in a dedicated workflow step. This retains Visual Studio 2022 until Electron's node-gyp recognizes the Visual Studio 2026 toolchain used by windows-latest.
  • Run .github/scripts/setup-node-gyp-python.sh "$RUNNER_TEMP/node-gyp-python" before bun install, then set PYTHON, npm_config_python, and npm_config_node_gyp from step outputs for the install step.
  • Windows CI run 22405749378 (2026-02-25) exposed a native rebuild failure in Install (Windows): bun install can fail with Executable not found in $PATH: "node-gyp.cmd".
  • Mitigate this Windows-only failure mode by running bun install --ignore-scripts before the full bun install, then prepending node_modules/.bin to PATH so node-gyp.cmd is available during native rebuild.
  • Do not use npm install for this bootstrap in this repository: npm can fail early on the repository override graph (Override without name) before Bun install starts.
  • After the scriptless Bun bootstrap, ensure node_modules/.bin/node-gyp.cmd exists. Bun's Windows package shim can expose node-gyp without the .cmd wrapper; create a minimal node-gyp.cmd launcher that delegates to ..\node-gyp\bin\node-gyp.js before running bun install.
  • For Windows install, map TMP, TEMP, and npm_config_tmp to ${{ runner.temp }} so node-gyp extraction uses a deterministic writable path instead of the short-name %LOCALAPPDATA% alias.
  • bin/download-mksnapshot.js now retries transient artefact download failures (for example, ECONNRESET, timeout/DNS errors, and 5xx/429 responses) with exponential backoff before failing the installation.
  • Tune retry behaviour with MKSNAPSHOT_DOWNLOAD_RETRY_ATTEMPTS (default 4) and MKSNAPSHOT_DOWNLOAD_RETRY_DELAY_MS (default 1000) when debugging unstable network environments.
  • Keep npm_config_node_gyp in the forward-slash form used by the Install (Windows) step in .github/workflows/nodejs.yml: ${{ github.workspace }}/node_modules/node-gyp/bin/node-gyp.js. Preserve this forward-slash npm_config_node_gyp value to avoid introducing path-separator regressions.
  • Keep bin/rebuild-node-pty.cjs running node-gyp through the Node executable (NODE environment variable when present, otherwise node on PATH), not process.execPath. CI runs this script via Bun; invoking node-gyp with Bun can trigger Windows header-extraction EINVAL failures.
  • Keep repository script/config text files normalized to LF in .gitattributes for extensions checked by Biome (*.json, *.jsonc, *.js, *.cjs, *.mjs, *.ts, and *.tsx). Windows checkout can otherwise convert those files to CRLF and trip make lint/Biome formatting checks.
  • Windows aarch64 CI is currently blocked by upstream Bun distribution support. Evidence (captured 2026-02-25): latest Bun release bun-v1.3.9 (published 2026-02-08) includes bun-windows-x64* assets and no Windows arm64 asset.
  • Mitigation and ownership are tracked in WINARM64-001 in docs/tracking-issues.md (issue: #35, owner: @leynos). Re-evaluate lane enablement when a Bun release publishes a Windows arm64 artefact and setup-bun supports it.

When preparing future Electron upgrades, update these anchors together and avoid merging partial baseline updates.