Expert Electron desktop application development — main/renderer process architecture, IPC communication, native OS APIs (menus, tray, notifications, dialogs), auto-updates, code signing, packaging with electron-builder/forge, security hardening (contextIsolation, sandbox), and performance optimization. Use for building cross-platform desktop apps.
Expert Electron desktop application development — main/renderer process architecture, IPC communication, native OS APIs (menus, tray, notifications, dialogs), auto-updates, code signing, packaging with electron-builder/forge, security hardening (contextIsolation, sandbox), and performance optimization. Use for building cross-platform desktop apps.
version
1.0.0
model
sonnet
invoked_by
both
user_invocable
true
tools
["Bash","Read","Write","Edit"]
best_practices
["Always enable contextIsolation and disable nodeIntegration in renderer","Use contextBridge to expose limited APIs to renderer","Never use remote module (deprecated and insecure)","Validate all IPC messages in main process","Use webContents.session for network interception"]
error_handling
graceful
streaming
not_applicable
verified
false
lastVerifiedAt
"2026-03-14T00:00:00.000Z"
source
builtin
trust_score
100
provenance_sha
80f0f303c91643b1
Electron Pro Skill
Overview
Full-stack Electron desktop app development — from architecture through distribution. Covers process model, security hardening, native OS integration, IPC patterns, packaging, and auto-update.
Process Architecture
┌─────────────────────────────────────┐
│ Main Process │
│ (Node.js — full system access) │
│ app, BrowserWindow, Menu, Tray │
│ nativeImage, shell, ipcMain │
└──────────────┬──────────────────────┘
│ IPC (structured clone)
┌──────────────┴──────────────────────┐
│ Renderer Process │
│ (Chromium — sandboxed by default) │
│ Web UI: React/Vue/Svelte/vanilla │
│ ipcRenderer (via contextBridge) │
└─────────────────────────────────────┘
│ contextBridge
┌──────────────┴──────────────────────┐
│ Preload Script │
│ Bridge between main and renderer │
│ Exposes safe APIs via contextBridge│
└─────────────────────────────────────┘
Security-First Setup (MANDATORY)
// main.js — Always use these security optionsconst win = newBrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true, // REQUIRED: isolates renderer from preloadsandbox: true, // RECOMMENDED: OS-level sandboxnodeIntegration: false, // REQUIRED: never expose Node to rendererwebSecurity: true, // REQUIRED: never disableallowRunningInsecureContent: false,
},
});
// NEVER do this — security violation:// nodeIntegration: true// contextIsolation: false// Use remote: require('@electron/remote') only if absolutely necessary
const { shell } = require('electron');
// Open in default browser/app — safe for user-initiated actionsawait shell.openExternal('https://example.com');
// Open file in default appawait shell.openPath('/path/to/file.pdf');
// Reveal in Finder/Explorer
shell.showItemInFolder('/path/to/file');
App Lifecycle
const { app, BrowserWindow } = require('electron');
let mainWindow = null;
functioncreateWindow() {
mainWindow = newBrowserWindow({
width: 1200,
height: 800,
show: false, // Wait for ready-to-show to avoid flashwebPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
nodeIntegration: false,
},
});
mainWindow.loadFile('index.html');
// Or for dev server: mainWindow.loadURL('http://localhost:5173');
mainWindow.once('ready-to-show', () => mainWindow.show());
mainWindow.on('closed', () => {
mainWindow = null;
});
}
app.whenReady().then(() => {
createWindow();
// macOS: re-create on activate if no windows
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
// Quit on all windows closed (except macOS)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit();
});
Auto-Update (electron-updater)
const { autoUpdater } = require('electron-updater');
autoUpdater.checkForUpdatesAndNotify();
autoUpdater.on('update-available', info => {
win.webContents.send('update-available', info);
});
autoUpdater.on('update-downloaded', info => {
win.webContents.send('update-downloaded', info);
});
// Triggered by renderer when user clicks "Install"
ipcMain.handle('install-update', () => {
autoUpdater.quitAndInstall();
});
# Start dev with hot reload (electron-vite recommended)
pnpm exec electron-vite dev
# Or with webpack/parcel
concurrently "pnpm build:renderer --watch""wait-on http://localhost:5173 && electron ."# Open DevTools programmatically (dev only)if (process.env.NODE_ENV === 'development') {
win.webContents.openDevTools();
}
# Debug main process
electron --inspect=9229 .
# Then attach Chrome DevTools at chrome://inspect
Anti-Patterns
nodeIntegration: true — exposes all of Node.js to web content (RCE vector)
contextIsolation: false — allows renderer to access preload scope directly
webSecurity: false — disables CORS and mixed content protections
shell.openExternal(userInput) without validation — SSRF/open redirect vector
eval() or Function() in renderer — CSP bypass
Storing secrets in renderer process — use main process + keychain
Using remote module — deprecated, insecure, causes memory leaks
Security Checklist
contextIsolation: true on all windows
nodeIntegration: false on all windows
sandbox: true enabled
CSP header set on loaded HTML
All IPC inputs validated in main process
No shell.openExternal(untrustedUrl) without validation
webSecurity: true (default, do not disable)
Code signed for distribution (macOS notarization required)