# electron-rebuild, recompiling native modules against the Electron you ship

> electron-rebuild fixes the ABI mismatch that appears when a native Node module was compiled against a different Node version than the one inside Electron. It downloads a matching prebuilt binary when one exists, falls back to node-gyp otherwise, and it ships as both a CLI and a small library.

**electron/rebuild** — Package to rebuild native Node.js modules against the currently installed Electron version

- Repository: https://github.com/electron/rebuild
- Stars: 1,123 · Forks: 182
- Language: TypeScript
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/electron-rebuild

## The problem is an ABI, not a version string

A native Node module is a compiled binary that talks to the Node runtime through an ABI. When you install such a module with npm, it is compiled against the ABI of the Node.js on your machine, and when that binary is loaded inside Electron, Electron is running a different Node version with a different ABI, and the module fails to load. The documentation puts it plainly, that this is often not the case and sometimes not even possible, since the system Node and the Node inside Electron cannot both match your requirements. The tool exists to remove that constraint. It rebuilds native modules against the version of Node.js that your Electron project is using, so a machine with Node 22 can produce an application that bundles Electron 39 and still run its native code. The audience is every developer who has hit a module that installed cleanly and then threw an ABI error at runtime, which is a failure that arrives late and confuses people who have never seen it.

## Prebuilds first, compilation second

The mechanism has two paths, and the tool picks between them. If the module uses prebuild, it also uses prebuild-install to download prebuilt binaries, and electron-rebuild runs prebuild-install to fetch the correct binaries from the project's GitHub Releases rather than compiling anything. The prebuild tag prefix is configurable and defaults to v, which is what lets the download step ask for the right artefact. If there is no matching prebuild, the module is built from source with node-gyp, which the documentation names as the tool used for building native modules and links to for its own installation and runtime requirements. The dependency list explains the rest. node-abi and node-api-version map an Electron release to the right ABI number, read-binary-file-arch inspects an existing binary to work out its architecture, and @malept/cross-spawn-promise runs the child processes, which matters on Windows where spawning a tool with a path and arguments behaves differently. The disable-pre-gyp-copy option exists to skip a copy step, and build-from-source forces the compilation path even when a prebuild could have been downloaded.

## Installing it and running it

The package is a development dependency, since it is part of the build, not the application.

```bash
npm install --save-dev @electron/rebuild
```

After any npm install that changes the dependency tree, the documented advice is to rerun the rebuild command.

```bash
$(npm bin)/electron-rebuild
```

On Windows the equivalent invocation uses the command shim in the local node_modules directory.

```bash
.\node_modules\.bin\electron-rebuild.cmd
```

There is a Windows specific failure mode worth knowing about. If you already have a working node-gyp configuration and you see an error about a missing element such as Could not load the Visual C++ component "VCBuild.exe", the documentation suggests launching the rebuild from an npm script instead.

```json
"scripts": {
  "rebuild": "electron-rebuild -f -w yourmodule"
}
```

Running npm run rebuild then goes through the script environment, which tends to resolve that particular Visual Studio tooling problem. The force flag rebuilds a module even when the tool would otherwise skip it, and the which-module argument narrows the run to one module.

## The CLI options, and the dependency types that are skipped

The command line surface is wide, which is what you would expect from a tool that has to work across three platforms and two build paths. The version flag sets the Electron version to build against, the arch flag overrides the target architecture to something other than the current system's, and the module-dir flag points at a node_modules directory other than the default. The only and which-module flags differ in an important way. A module named with which-module is rebuilt only if it also matches the types of dependencies being rebuilt, while only builds the named modules and ignores everything else. The types flag takes a comma separated list of prod, dev and optional, and its default is prod,optional, which means devDependencies are not rebuilt. That default has a consequence the documentation calls out explicitly, since a native module living in devDependencies has to be requested by name.

```bash
electron-rebuild --types prod,optional,dev
```

The parallel flag is on by default on macOS and Linux and the sequential flag is the default on Windows, so the platform decides the concurrency unless you override it. The jobs flag passes a compile job count through to node-gyp, and the use-electron-clang flag selects the clang that Electron itself was built with, which the documentation describes as guaranteeing compiler compatibility. The force-abi flag overrides the ABI version and is meant for targeting Nightly releases only. The dist-url flag sets a custom header tarball URL, and it can also come from the ELECTRON_REBUILD_DIST_URL environment variable, with the flag taking precedence when both are set.

## It plugs into Forge, Packager and prebuild pipelines

Most Electron teams never call the CLI by hand in the end, because the tool is wired into the packaging tools. With Electron Forge it is used automatically when packaging an application. With Electron Packager the library exposes a function that matches the afterCopy hook, and the example shows the shape.

```javascript
import { packager } from "@electron/packager";
import { rebuild } from "@electron/rebuild";

packager({
  afterCopy: [
    async ({ buildPath, electronVersion, arch }) => {
      await rebuild({ buildPath, electronVersion, arch });
    },
  ],
});
```

The three arguments the hook provides are exactly what the rebuild needs, the build path, the Electron version and the architecture, which is why the integration is short. The prebuild integration works the other way round, in the sense that a module using prebuild also uses prebuild-install, and the rebuild command will run prebuild-install to fetch the right binaries from the project releases instead of rebuilding. The same function is available to a build pipeline that wants to require the package directly, and the documentation describes the API as very simple.

## The toolchain you inherit when it compiles

The stated requirement is Node v22.12.0 or higher, and the package metadata enforces the same floor with an engines field. The repository confirms the shape of a modern TypeScript package, with sources in src/, tests in test/, a vitest.config.ts, a tsconfig.json and a typings/ directory, and the build itself is a plain tsc compile with typedoc generating the API documentation from src/main.ts. The linting setup is oxlint with oxfmt for formatting, husky manages the git hooks, and the package publishes with provenance enabled. The interesting operational detail is the prewarm-headers script, which runs node-gyp install --ensure, because a cold node-gyp has to download the Node headers for the target version before anything can be compiled, and doing that at test time rather than build time makes the test run depend on the network. The nvmrc file pins the Node version used for development. On the release side, tags v4.1.0, v4.2.0 and v4.2.1 came on 2026-07-01, 2026-07-07 and 2026-10-06, the last push to the default branch was on 2026-10-15, and the licence is MIT.

## Where it is the wrong tool

The clearest case is an application with no native dependencies, where the whole exercise is unnecessary. The second is a project that cannot run a compiler on the build machine, because a source rebuild needs node-gyp, the Node headers for the target version, and a working C or C++ toolchain, and the container images that solve this for other ecosystems do not exist for this problem in the documentation. The third is a module whose prebuilds are not published for your target, where the download path fails and you fall back to a source build that may not compile against that Electron release, and where the only signal you get is a compile error rather than a message saying the prebuild was missing. A fourth consideration is the scope of what gets touched. A rebuild operates on the node_modules tree, and the default of prod,optional means a devDependency native module stays compiled for the system Node, which is fine until a script that runs inside Electron loads it. The tool does the mechanical part well, and the judgement about which modules need it stays with the team.

## Conclusion

electron-rebuild fits a team shipping an Electron application that depends on native modules, especially where the development machine's Node version and the bundled Electron version disagree, since the tool rebuilds against the version you actually ship. It does not fit a JavaScript only application, where there is nothing to rebuild, and it does not fit a team that cannot install a native toolchain on the build machine, because building from source needs node-gyp and a working compiler. Verify three things first: that the Electron version you pass to it matches the one in your lockfile, whether the modules in your devDependencies need rebuilding, since they are skipped by default, and whether the prebuild your module publishes is actually tagged for your target architecture and Electron release.

## FAQ

### What does electron-rebuild do?

It rebuilds native Node.js modules against the version of Node.js that your Electron project uses, so native modules work in an Electron app without your system Node version matching exactly. The package is installed as @electron/rebuild and provides an electron-rebuild command.

### How do I rebuild native modules for Electron?

Install it with npm install --save-dev @electron/rebuild and run the command after npm installs, using $(npm bin)/electron-rebuild, or .\node_modules\.bin\electron-rebuild.cmd on Windows. Running it from an npm script is the documented workaround for a missing VCBuild.exe error on Windows.

### Does electron-rebuild rebuild devDependencies?

No. The default for the types option is prod,optional, so devDependencies are skipped. You have to ask for them explicitly, for example with electron-rebuild --types prod,optional,dev or by passing types in the API.

### How does electron-rebuild handle modules that publish prebuilds?

If a module uses prebuild it also uses prebuild-install, and electron-rebuild runs prebuild-install to download the matching binaries from the project GitHub Releases instead of compiling. The --build-from-source flag skips the download and rebuilds from source.

## Sources

- [electron/rebuild on GitHub](https://github.com/electron/rebuild)
- [Issues](https://github.com/electron/rebuild/issues)
- [License: MIT](https://github.com/electron/rebuild/blob/main/LICENSE)
- [README](https://github.com/electron/rebuild/blob/main/README.md)
- [Releases](https://github.com/electron/rebuild/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/electron-rebuild
