Electron
Electron is an open-source framework developed by GitHub for building cross-platform desktop applications using web technologies like JavaScript, HTML, and CSS. It embeds Chromium and Node.js into a single runtime, allowing developers to create applications that run on Windows, macOS, and Linux from a single codebase. The current stable version is 41.2.1, with frequent patch and minor updates and a steady stream of beta releases (currently v42.0.0-beta.4) indicating an active and rapid development cycle. Key differentiators include its ability to leverage existing web development skills for desktop app creation, a large ecosystem of tools and libraries, and strong community support, making it a popular choice for apps requiring native system access and rich UI capabilities.
Common errors
-
Error: require() of ES Module ... not supported. Instead change the require of ... to a dynamic import()
cause Attempting to `require()` an ES Module (ESM) in a CommonJS context, typically in the main process.fixFor an ESM module, use `import()` dynamically or ensure your main process entry file is an ES Module (e.g., `"type": "module"` in `package.json` and use `.mjs` extension) to use top-level `import` statements. Or, find a CommonJS compatible version of the dependency. -
Uncaught ReferenceError: require is not defined
cause Attempting to use `require()` in a renderer process where `nodeIntegration` is `false` (which is the secure default).fixAccess Node.js APIs and other main process functionalities securely via a preload script with `contextIsolation: true`. Expose necessary functions from the preload script to the renderer's `window` object, or use `ipcRenderer` to communicate with the main process. -
Cannot read properties of undefined (reading 'send') or 'invoke')
cause Trying to use `ipcRenderer.send` or `ipcRenderer.invoke` in the renderer process, but the `ipcRenderer` object is not available or properly exposed due to `contextIsolation`.fixEnsure `contextIsolation: true` is set in `webPreferences`. In your `preload.js` script, use `contextBridge.exposeInMainWorld` to selectively expose an API to the renderer process, which then uses `window.myAPI.send(...)` or `window.myAPI.invoke(...)`.
Warnings
- breaking Electron's core APIs (like `BrowserWindow`, `Menu`, etc.) often have breaking changes between major versions due to Chromium and Node.js updates, or refactoring for security and stability. Always consult the migration guide for each major version upgrade.
- breaking The default values for `nodeIntegration` and `contextIsolation` in `webPreferences` have changed over time and are now `false` and `true` respectively by default. Disabling `nodeIntegration` and enabling `contextIsolation` is a critical security hardening measure.
- gotcha Electron's `remote` module was deprecated and eventually removed to improve security and maintainability. Direct access to main process modules from the renderer process is no longer supported.
- deprecated Many Electron APIs, especially those related to deprecated Chromium features or security vulnerabilities, may become deprecated or removed without a full major version bump, typically with a warning in the console.
- gotcha Packaging and distributing Electron applications can be complex, especially with native modules. Misconfiguration of `electron-builder` or `electron-packager` can lead to broken builds or platform-specific issues.
Install
-
npm install electron -
yarn add electron -
pnpm add electron
Imports
- app
const { app, BrowserWindow } = require('electron')import { app, BrowserWindow } from 'electron' - BrowserWindow
import BrowserWindow from 'electron'
import { BrowserWindow } from 'electron' - ipcRenderer
import { ipcRenderer } from 'electron' - globalShortcut
import { globalShortcut } from 'electron'
Quickstart
import { app, BrowserWindow } from 'electron';
import path from 'path';
const createWindow = () => {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: false, // Strongly recommended to be false for security
contextIsolation: true // Strongly recommended to be true for security
}
});
mainWindow.loadFile('index.html');
// Open the DevTools.
// mainWindow.webContents.openDevTools();
};
app.whenReady().then(() => {
createWindow();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit();
});