Build Electron Main/Preload ESM
build-electron is a specialized command-line tool designed to simplify the use of ES Modules (ESM) in Electron's main and preload processes. It targets the persistent challenge of Electron's lack of native ESM support by providing a pre-configured Webpack 5 build system, abstracting away complex configurations. It is currently at version 1.0.5 and appears to have an infrequent release cadence, with minor fixes and updates being pushed when needed. Its key differentiator is its focus solely on the Electron main/preload code, intentionally avoiding renderer code to keep the tool simple and framework-agnostic. This allows developers to pair it with existing frontend build tools like Create React App without conflict, aiming for a plug-and-play experience until Electron natively supports ESM. It is not a boilerplate but a build utility.
Common errors
-
Error: Cannot use import statement outside a module
cause Attempting to use ES Modules (`import`/`export`) directly in Electron's main or preload process without prior transpilation or bundling.fixEnsure `build-electron` is configured and executed correctly to process your main and preload files, transforming them into a format Electron can understand (e.g., CommonJS). -
Error: Entrypoint undefined. Please specify mainEntry and preloadEntry in build-electron.config.js
cause The `build-electron.config.js` file is missing, or the `mainEntry` and `preloadEntry` properties are not defined or are pointing to non-existent files.fixCreate or verify `build-electron.config.js` in your project root and ensure `mainEntry` and `preloadEntry` are correctly specified with valid paths to your source files. -
Error: spawn electron ENOENT
cause The `electron` executable could not be found when running the `start` script, typically because `electron` is not installed or not in the system's PATH.fixInstall `electron` as a dev dependency (`yarn add -D electron` or `npm install --save-dev electron`) and ensure your `package.json` scripts are correctly set up to use the locally installed binary (e.g., `electron .`). -
Error: build-electron failed with exit code 1
cause A generic error indicating a build failure within `build-electron`, often due to syntax errors in source files, incorrect configuration, or issues with webpack dependencies.fixCheck the console output for more specific Webpack or compilation errors that precede this message. Review your source code for syntax issues and verify `build-electron.config.js` for correctness.
Warnings
- gotcha Electron's core runtime does not natively support ES Modules (ESM) for Node.js integration, which is the primary problem `build-electron` aims to solve. This means without a tool like `build-electron`, you cannot directly use `import`/`export` syntax in your Electron main or preload scripts for Node.js modules or your own files.
- gotcha `build-electron` is explicitly designed only for Electron's `main` and `preload` processes. It does not handle frontend (renderer process) code. Developers must use separate tools (e.g., Create React App, Vite, Webpack) for their renderer-side JavaScript, TypeScript, and UI frameworks.
- breaking The `mainTarget` and `preloadTarget` configuration options (e.g., `electron16.0-main`) are tightly coupled to specific Electron versions. Using an incorrect or outdated target might lead to build failures or runtime issues due to API changes or environment mismatches.
- gotcha When integrating with other tools like `electron-builder` or `Create React App`, careful attention must be paid to file paths and output directories. Conflicting `outDir` settings or incorrect references to built files can lead to 'file not found' errors or blank Electron windows.
Install
-
npm install build-electron -
yarn add build-electron -
pnpm add build-electron
Quickstart
yarn add -D build-electron concurrently wait-on electron electron-builder
// build-electron.config.js
module.exports = {
mainEntry: 'src/main/index.js',
preloadEntry: 'src/preload/index.js',
outDir: 'build',
mainTarget: 'electron27.0-main', // Adjust target Electron version as needed
preloadTarget: 'electron27.0-preload',
};
// package.json (add to scripts and config)
{
"main": "build/main.js",
"build": {
"files": [
"build/**/*"
]
},
"scripts": {
"start": "concurrently -k \"build-electron -d\" \"wait-on build/.build-electron-done && electron .\"",
"build": "build-electron"
}
}
// src/main/index.js (example Electron main process entry)
import { app, BrowserWindow } from 'electron';
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: require.resolve('../build/preload.js') // Ensure correct path to built preload
}
});
win.loadFile('index.html'); // Or load a URL
}
app.whenReady().then(() => {
createWindow();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
// To run:
npm run start
// To build for production (e.g., for macOS):
npm run build && npx electron-builder --mac