2021-08-16 12:12:34 +00:00
# Native Node Modules
2013-09-09 07:35:57 +00:00
2020-12-08 04:28:59 +00:00
Native Node.js modules are supported by Electron, but since Electron has a different
[application binary interface (ABI)][abi] from a given Node.js binary (due to
differences such as using Chromium's BoringSSL instead of OpenSSL), the native
modules you use will need to be recompiled for Electron. Otherwise,
2019-04-24 17:32:37 +00:00
you will get the following class of error when you try to run your app:
```sh
Error: The module '/path/to/native/module.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION $XYZ. This version of Node.js requires
NODE_MODULE_VERSION $ABC. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or `npm install` ).
```
2014-09-08 07:07:33 +00:00
2016-06-16 08:10:57 +00:00
## How to install native modules
2014-04-30 07:03:14 +00:00
2019-04-24 17:32:37 +00:00
There are several different ways to install native modules:
### Installing modules and rebuilding for Electron
You can install modules like other Node projects, and then rebuild the modules
2023-03-31 09:36:59 +00:00
for Electron with the [`@electron/rebuild`][@electron/rebuild] package. This
2019-04-24 17:32:37 +00:00
module can automatically determine the version of Electron and handle the
manual steps of downloading headers and rebuilding native modules for your app.
2020-12-08 04:28:59 +00:00
If you are using [Electron Forge][electron-forge], this tool is used automatically
in both development mode and when making distributables.
2019-04-24 17:32:37 +00:00
2023-03-31 09:36:59 +00:00
For example, to install the standalone `@electron/rebuild` tool and then rebuild
2020-12-08 04:28:59 +00:00
modules with it via the command line:
2019-04-24 17:32:37 +00:00
```sh
2023-03-31 09:36:59 +00:00
npm install --save-dev @electron/rebuild
2019-04-24 17:32:37 +00:00
# Every time you run "npm install", run this:
./node_modules/.bin/electron-rebuild
2020-12-08 04:28:59 +00:00
# If you have trouble on Windows, try:
2019-04-24 17:32:37 +00:00
.\node_modules\.bin\electron-rebuild.cmd
```
2024-06-10 15:14:03 +00:00
For more information on usage and integration with other tools such as
[Electron Packager][electron-packager], consult the project's README.
2015-10-05 14:48:48 +00:00
2016-06-16 08:10:57 +00:00
### Using `npm`
2014-04-30 07:03:14 +00:00
2016-06-16 08:10:57 +00:00
By setting a few environment variables, you can use `npm` to install modules
directly.
2015-09-01 02:22:06 +00:00
2019-04-24 17:32:37 +00:00
For example, to install all dependencies for Electron:
2014-02-20 10:51:57 +00:00
2017-11-24 10:13:57 +00:00
```sh
2016-06-16 08:10:57 +00:00
# Electron's version.
export npm_config_target=1.2.3
2023-03-31 09:36:59 +00:00
# The architecture of your machine
2016-06-16 08:10:57 +00:00
export npm_config_arch=x64
2016-09-22 15:46:31 +00:00
export npm_config_target_arch=x64
2016-06-16 08:10:57 +00:00
# Download headers for Electron.
2019-05-21 07:17:08 +00:00
export npm_config_disturl=https://electronjs.org/headers
2016-06-16 08:10:57 +00:00
# Tell node-pre-gyp that we are building for Electron.
export npm_config_runtime=electron
# Tell node-pre-gyp to build module from source code.
export npm_config_build_from_source=true
# Install all dependencies, and store cache to ~/.electron-gyp.
HOME=~/.electron-gyp npm install
```
2015-05-05 05:39:55 +00:00
2016-06-16 08:10:57 +00:00
### Manually building for Electron
2014-02-20 10:51:57 +00:00
2016-06-16 08:10:57 +00:00
If you are a developer developing a native module and want to test it against
Electron, you might want to rebuild the module for Electron manually. You can
use `node-gyp` directly to build for Electron:
2013-08-14 22:43:35 +00:00
2017-11-24 10:13:57 +00:00
```sh
2016-06-16 08:10:57 +00:00
cd /path-to-module/
2019-05-21 07:17:08 +00:00
HOME=~/.electron-gyp node-gyp rebuild --target=1.2.3 --arch=x64 --dist-url=https://electronjs.org/headers
2013-08-14 22:43:35 +00:00
```
2019-04-24 17:32:37 +00:00
* `HOME=~/.electron-gyp` changes where to find development headers.
* `--target=1.2.3` is the version of Electron.
* `--dist-url=...` specifies where to download the headers.
* `--arch=x64` says the module is built for a 64-bit system.
2016-06-16 08:10:57 +00:00
2018-08-24 21:28:11 +00:00
### Manually building for a custom build of Electron
2019-04-24 17:32:37 +00:00
To compile native Node modules against a custom build of Electron that doesn't
2018-08-24 21:28:11 +00:00
match a public release, instruct `npm` to use the version of Node you have bundled
with your custom build.
```sh
2021-04-28 07:38:08 +00:00
npm rebuild --nodedir=/path/to/src/out/Default/gen/node_headers
2018-08-24 21:28:11 +00:00
```
2016-06-16 08:10:57 +00:00
## Troubleshooting
If you installed a native module and found it was not working, you need to check
2019-04-24 17:32:37 +00:00
the following things:
2016-06-16 08:10:57 +00:00
2023-03-31 09:36:59 +00:00
* When in doubt, run `@electron/rebuild` first.
2019-04-24 17:32:37 +00:00
* Make sure the native module is compatible with the target platform and
architecture for your Electron app.
* Make sure `win_delay_load_hook` is not set to `false` in the module's `binding.gyp` .
* After you upgrade Electron, you usually need to rebuild the modules.
2016-06-16 08:10:57 +00:00
2018-11-20 00:13:50 +00:00
### A note about `win_delay_load_hook`
2019-04-24 17:32:37 +00:00
On Windows, by default, `node-gyp` links native modules against `node.dll` .
2018-11-20 00:13:50 +00:00
However, in Electron 4.x and higher, the symbols needed by native modules are
2019-04-24 17:32:37 +00:00
exported by `electron.exe` , and there is no `node.dll` . In order to load native
2024-06-10 15:14:03 +00:00
modules on Windows, `node-gyp` installs a
[delay-load hook ](https://learn.microsoft.com/en-us/cpp/build/reference/error-handling-and-notification?view=msvc-170#notification-hooks ) that triggers
2018-11-20 00:13:50 +00:00
when the native module is loaded, and redirects the `node.dll` reference to use
the loading executable instead of looking for `node.dll` in the library search
path (which would turn up nothing). As such, on Electron 4.x and higher,
`'win_delay_load_hook': 'true'` is required to load native modules.
2019-02-06 16:29:58 +00:00
If you get an error like `Module did not self-register` , or `The specified
procedure could not be found`, it may mean that the module you're trying to use
did not correctly include the delay-load hook. If the module is built with
node-gyp, ensure that the `win_delay_load_hook` variable is set to `true` in
the `binding.gyp` file, and isn't getting overridden anywhere. If the module
is built with another system, you'll need to ensure that you build with a
delay-load hook installed in the main `.node` file. Your `link.exe` invocation
should look like this:
2019-07-30 20:11:56 +00:00
```plaintext
2019-02-06 16:29:58 +00:00
link.exe /OUT:"foo.node" "...\node.lib" delayimp.lib /DELAYLOAD:node.exe /DLL
"my_addon.obj" "win_delay_load_hook.obj"
```
In particular, it's important that:
2020-11-23 17:15:27 +00:00
* you link against `node.lib` from _Electron_ and not Node. If you link against
2019-02-06 16:29:58 +00:00
the wrong `node.lib` you will get load-time errors when you require the
module in Electron.
2020-11-23 17:15:27 +00:00
* you include the flag `/DELAYLOAD:node.exe` . If the `node.exe` link is not
2019-02-06 16:29:58 +00:00
delayed, then the delay-load hook won't get a chance to fire and the node
symbols won't be correctly resolved.
2020-11-23 17:15:27 +00:00
* `win_delay_load_hook.obj` is linked directly into the final DLL. If the hook
2019-02-06 16:29:58 +00:00
is set up in a dependent DLL, it won't fire at the right time.
2019-04-24 17:32:37 +00:00
See [`node-gyp` ](https://github.com/nodejs/node-gyp/blob/e2401e1395bef1d3c8acec268b42dc5fb71c4a38/src/win_delay_load_hook.cc )
for an example delay-load hook if you're implementing your own.
2019-02-06 16:29:58 +00:00
2016-12-10 19:23:33 +00:00
## Modules that rely on `prebuild`
2019-04-24 17:32:37 +00:00
[`prebuild` ](https://github.com/prebuild/prebuild ) provides a way to publish
native Node modules with prebuilt binaries for multiple versions of Node
2016-12-10 19:23:33 +00:00
and Electron.
2020-12-08 04:28:59 +00:00
If the `prebuild` -powered module provide binaries for the usage in Electron,
make sure to omit `--build-from-source` and the `npm_config_build_from_source`
environment variable in order to take full advantage of the prebuilt binaries.
2016-12-10 19:23:33 +00:00
2016-06-16 08:10:57 +00:00
## Modules that rely on `node-pre-gyp`
The [`node-pre-gyp` tool][node-pre-gyp] provides a way to deploy native Node
modules with prebuilt binaries, and many popular modules are using it.
2020-12-08 04:28:59 +00:00
Sometimes those modules work fine under Electron, but when there are no
Electron-specific binaries available, you'll need to build from source.
2023-03-31 09:36:59 +00:00
Because of this, it is recommended to use `@electron/rebuild` for these modules.
2016-06-16 08:10:57 +00:00
2020-12-08 04:28:59 +00:00
If you are following the `npm` way of installing modules, you'll need to pass
`--build-from-source` to `npm` , or set the `npm_config_build_from_source`
environment variable.
2016-06-16 08:10:57 +00:00
2020-12-08 04:28:59 +00:00
[abi]: https://en.wikipedia.org/wiki/Application_binary_interface
2023-03-31 09:36:59 +00:00
[@electron/rebuild]: https://github.com/electron/rebuild
2020-12-08 04:28:59 +00:00
[electron-forge]: https://electronforge.io/
2023-11-09 19:15:32 +00:00
[electron-packager]: https://github.com/electron/packager
2016-06-16 08:10:57 +00:00
[node-pre-gyp]: https://github.com/mapbox/node-pre-gyp