electron-patterns

Electron Desktop Patterns

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "electron-patterns" with this command: npx skills add 5dlabs/cto/5dlabs-cto-electron-patterns

Electron Desktop Patterns

Cross-platform desktop development with Electron, covering security, IPC, and native integrations.

Core Stack

Component Library Purpose

Framework Electron 28+ Desktop apps

Build electron-builder, electron-forge Packaging

Language TypeScript 5+ (strict) Type safety

UI React/shadcn/ui Renderer process

Testing Playwright, Vitest E2E and unit tests

Updates electron-updater Auto-update

Context7 Library IDs

Query these libraries for current best practices:

  • Electron: /electron/electron

  • electron-builder: /electron-userland/electron-builder

  • Better Auth: /better-auth/better-auth

Architecture

┌─────────────────────────────────────────────────┐ │ Main Process │ │ (Node.js - full system access) │ │ - Window management │ │ - Native menus, tray, notifications │ │ - File system, auto-update │ │ - IPC handler │ └───────────────────┬─────────────────────────────┘ │ IPC (contextBridge) ┌───────────────────▼─────────────────────────────┐ │ Preload Script │ │ (Limited Node.js - contextBridge only) │ │ - Expose safe APIs to renderer │ │ - Type-safe IPC channels │ └───────────────────┬─────────────────────────────┘ │ ┌───────────────────▼─────────────────────────────┐ │ Renderer Process │ │ (Chromium - web context only) │ │ - React UI, shadcn/ui components │ │ - Uses window.api from preload │ └─────────────────────────────────────────────────┘

Security Rules

  • Context isolation always. Never expose Node.js to renderer

  • IPC for everything. Main ↔ Renderer via IPC only

  • Preload scripts. Use for secure API exposure

  • Code sign releases. Required for macOS/Windows

  • Auto-update. Use electron-updater

Main Process

// main.ts import { app, BrowserWindow, ipcMain, shell } from 'electron'; import path from 'path';

function createWindow() { const win = new BrowserWindow({ width: 1200, height: 800, webPreferences: { preload: path.join(__dirname, 'preload.js'), contextIsolation: true, // REQUIRED nodeIntegration: false, // REQUIRED sandbox: true, // RECOMMENDED }, });

// Open external links in browser win.webContents.setWindowOpenHandler(({ url }) => { shell.openExternal(url); return { action: 'deny' }; });

win.loadFile('index.html'); }

// IPC handlers ipcMain.handle('read-file', async (_, filePath: string) => { return fs.promises.readFile(filePath, 'utf-8'); });

Preload Script

// preload.ts import { contextBridge, ipcRenderer } from 'electron';

contextBridge.exposeInMainWorld('api', { readFile: (path: string) => ipcRenderer.invoke('read-file', path), onUpdateAvailable: (callback: () => void) => ipcRenderer.on('update-available', callback), });

Renderer Usage

// Type declaration declare global { interface Window { api: { readFile: (path: string) => Promise<string>; onUpdateAvailable: (callback: () => void) => void; }; } }

// React component function App() { const loadFile = async () => { const content = await window.api.readFile('/path/to/file'); }; }

Native Menus

import { Menu, shell } from 'electron';

const template: Electron.MenuItemConstructorOptions[] = [ { label: 'File', submenu: [ { label: 'New', accelerator: 'CmdOrCtrl+N', click: () => {} }, { type: 'separator' }, { role: 'quit' }, ], }, { label: 'Edit', submenu: [ { role: 'undo' }, { role: 'redo' }, { type: 'separator' }, { role: 'cut' }, { role: 'copy' }, { role: 'paste' }, ], }, ];

Menu.setApplicationMenu(Menu.buildFromTemplate(template));

System Tray

import { Tray, Menu, nativeImage } from 'electron';

const tray = new Tray(nativeImage.createFromPath('icon.png')); tray.setContextMenu(Menu.buildFromTemplate([ { label: 'Show App', click: () => mainWindow.show() }, { label: 'Quit', click: () => app.quit() }, ]));

Auto-Update

import { autoUpdater } from 'electron-updater';

autoUpdater.checkForUpdatesAndNotify();

autoUpdater.on('update-available', () => { mainWindow.webContents.send('update-available'); });

autoUpdater.on('update-downloaded', () => { autoUpdater.quitAndInstall(); });

electron-builder.yml

appId: com.company.myapp productName: MyApp directories: output: dist files:

  • "build/**/*"
  • "node_modules/**/*" mac: category: public.app-category.productivity hardenedRuntime: true gatekeeperAssess: false entitlements: "build/entitlements.mac.plist" entitlementsInherit: "build/entitlements.mac.plist" win: target: nsis linux: target:
    • AppImage
    • deb publish: provider: github

Hardened Runtime Entitlements

<!-- entitlements.mac.plist --> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "..."> <plist version="1.0"> <dict> <key>com.apple.security.cs.allow-jit</key> <true/> <key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/> <key>com.apple.security.cs.disable-library-validation</key> <true/> </dict> </plist>

Validation Commands

Type check

npx tsc --noEmit

Lint

npx eslint .

Tests

npm test

Build (without signing)

npm run build

Package for current platform

npm run package

Guidelines

  • Always use context isolation

  • Never expose Node.js to renderer

  • Use preload scripts for safe API exposure

  • Sign releases for distribution

  • Implement auto-update for seamless updates

  • Handle external links in default browser

  • Use native menus for platform conventions

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

expo-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

elysia-llm-docs

No summary provided by upstream source.

Repository SourceNeeds Review
General

better-auth-expo

No summary provided by upstream source.

Repository SourceNeeds Review
General

anime-js

No summary provided by upstream source.

Repository SourceNeeds Review