electron-best-practices

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Electron + React Best Practices

Electron + React 最佳实践

Guide AI agents in building secure, production-ready Electron applications with React. This skill provides security patterns, type-safe IPC communication, project setup guidance, packaging and code signing workflows, and tools for analysis, scaffolding, and type generation.
指导AI Agent构建基于React的安全、可用于生产环境的Electron应用。本技能提供安全模式、类型安全IPC通信、项目搭建指南、打包与代码签名工作流,以及用于分析、脚手架生成和类型生成的工具。

When to Use This Skill

何时使用本技能

Use this skill when:
  • Generating Electron main, preload, or renderer process code
  • Configuring electron-vite or Electron Forge
  • Setting up IPC communication between processes
  • Implementing security patterns (contextBridge, sandbox, CSP)
  • Packaging, signing, and notarizing desktop applications
  • Testing Electron apps with Playwright
  • Designing multi-window architectures
Do NOT use this skill when:
  • Building Tauri apps (different paradigm, use Tauri-specific guidance)
  • Building pure web apps with no desktop requirements
  • Targeting Electron versions below 20 (security defaults differ)
  • Using non-React renderer frameworks (use framework-specific skills)
在以下场景使用本技能:
  • 生成Electron主进程、预加载脚本或渲染进程代码
  • 配置electron-vite或Electron Forge
  • 搭建进程间IPC通信
  • 实现安全模式(contextBridge、沙箱、CSP)
  • 桌面应用的打包、签名与公证
  • 使用Playwright测试Electron应用
  • 设计多窗口架构
请勿在以下场景使用本技能:
  • 构建Tauri应用(不同技术范式,请使用Tauri专属指导)
  • 构建无桌面需求的纯Web应用
  • 针对低于20版本的Electron开发(安全默认配置不同)
  • 使用非React的渲染框架(请使用对应框架的专属技能)

Core Principles

核心原则

1. Security First Architecture

1. 安全优先架构

Modern Electron security relies on three defaults that became standard in Electron 20+: context isolation, sandbox mode, and nodeIntegration disabled. Disabling any of them allows XSS attacks to escalate to full remote code execution. All main-renderer communication must flow through contextBridge:
typescript
// preload.ts - SECURE pattern
contextBridge.exposeInMainWorld('electronAPI', {
  loadPreferences: () => ipcRenderer.invoke('load-prefs'),
  saveFile: (content: string) => ipcRenderer.invoke('save-file', content),
  onUpdateCounter: (callback: (value: number) => void) => {
    const handler = (_event: IpcRendererEvent, value: number) => callback(value);
    ipcRenderer.on('update-counter', handler);
    return () => ipcRenderer.removeListener('update-counter', handler);
  }
});
Set Content Security Policy via HTTP headers for apps loading local files, restricting script sources to
'self'
.
现代Electron安全依赖于Electron 20+成为标准的三项默认配置:上下文隔离、沙箱模式和禁用nodeIntegration。禁用其中任何一项都会让XSS攻击升级为完全的远程代码执行。所有主进程与渲染进程的通信必须通过contextBridge进行:
typescript
// preload.ts - 安全模式
contextBridge.exposeInMainWorld('electronAPI', {
  loadPreferences: () => ipcRenderer.invoke('load-prefs'),
  saveFile: (content: string) => ipcRenderer.invoke('save-file', content),
  onUpdateCounter: (callback: (value: number) => void) => {
    const handler = (_event: IpcRendererEvent, value: number) => callback(value);
    ipcRenderer.on('update-counter', handler);
    return () => ipcRenderer.removeListener('update-counter', handler);
  }
});
对于加载本地文件的应用,通过HTTP头设置内容安全策略(CSP),将脚本源限制为
'self'

2. Type-Safe IPC Communication

2. 类型安全IPC通信

The invoke/handle pattern is preferred over send/on for request-response communication, providing proper async/await semantics and error propagation. For typed channels, use a mapped type pattern:
typescript
type IpcChannelMap = {
  'load-prefs': { args: []; return: UserPreferences };
  'save-file': { args: [content: string]; return: { success: boolean } };
};
For complex applications, electron-trpc provides full type safety using tRPC's router pattern with Zod validation:
typescript
export const appRouter = t.router({
  greeting: t.procedure
    .input(z.object({ name: z.string() }))
    .query(({ input }) => `Hello, ${input.name}!`),
});
Error handling across the IPC boundary requires attention because Electron only serializes the
message
property of Error objects. Wrap responses in a
{ success, data, error }
result type to preserve full error context.
对于请求-响应式通信,推荐使用invoke/handle模式而非send/on,该模式提供了标准的async/await语义和错误传播机制。对于类型化通道,可使用映射类型模式:
typescript
type IpcChannelMap = {
  'load-prefs': { args: []; return: UserPreferences };
  'save-file': { args: [content: string]; return: { success: boolean } };
};
对于复杂应用,electron-trpc结合Zod验证,通过tRPC的路由模式提供完整的类型安全:
typescript
export const appRouter = t.router({
  greeting: t.procedure
    .input(z.object({ name: z.string() }))
    .query(({ input }) => `Hello, ${input.name}!`),
});
跨IPC边界的错误处理需要注意:Electron仅会序列化Error对象的
message
属性。请将响应包装为
{ success, data, error }
结果类型,以保留完整的错误上下文。

3. Modern Project Setup

3. 现代化项目搭建

The recommended stack uses electron-vite for development and Electron Forge for packaging. electron-vite provides a unified configuration managing main, preload, and renderer processes with sub-second dev server startup and instant HMR. Electron Forge uses first-party Electron packages for signing and notarization.
src/
├── main/           # Main process (Node.js environment)
│   ├── index.ts
│   └── ipc/        # IPC handlers
├── preload/        # Secure bridge via contextBridge
│   ├── index.ts
│   └── index.d.ts  # TypeScript declarations for exposed APIs
└── renderer/       # React application (pure web, no Node access)
    ├── src/
    └── index.html
推荐的技术栈使用electron-vite进行开发,Electron Forge进行打包。electron-vite提供统一的配置,管理主进程、预加载脚本和渲染进程,支持亚秒级的开发服务器启动和即时热模块替换(HMR)。Electron Forge使用Electron官方包进行签名和公证。
src/
├── main/           # 主进程(Node.js环境)
│   ├── index.ts
│   └── ipc/        # IPC处理器
├── preload/        # 通过contextBridge实现安全桥接
│   ├── index.ts
│   └── index.d.ts  # 暴露API的TypeScript声明
└── renderer/       # React应用(纯Web环境,无Node权限)
    ├── src/
    └── index.html

4. React Integration Patterns

4. React集成模式

React 18's concurrent features work normally in Electron's Chromium-based renderer. Strict Mode's double-invocation of effects catches IPC listener leaks that would otherwise cause memory issues. Always return cleanup functions from effects that register IPC listeners:
typescript
useEffect(() => {
  const cleanup = window.electronAPI.onUpdateCounter((value) => {
    setCount(value);
  });
  return cleanup;
}, []);
For multi-window applications, the main process should serve as the single source of truth for shared state. Use electron-store for persistence combined with IPC broadcasting so any window's mutation updates all others.
React 18的并发特性可在Electron基于Chromium的渲染器中正常工作。严格模式下的效果双调用机制可捕获IPC监听器泄漏问题,否则会导致内存问题。注册IPC监听器的effect必须始终返回清理函数:
typescript
useEffect(() => {
  const cleanup = window.electronAPI.onUpdateCounter((value) => {
    setCount(value);
  });
  return cleanup;
}, []);
对于多窗口应用,主进程应作为共享状态的单一可信源。结合electron-store进行持久化,并通过IPC广播实现:任何窗口的状态变更都会同步更新所有其他窗口。

Quick Reference

快速参考

CategoryPreferAvoid
Security
contextBridge.exposeInMainWorld()
nodeIntegration: true
IPC
invoke/handle
pattern
send/on
for request-response
PreloadTyped function wrappersExposing raw
ipcRenderer
Build toolelectron-vitewebpack-based toolchains
PackagingElectron ForgeManual packaging
StateZustand + electron-storeRedux for simple apps
TestingPlaywright E2ESpectron (deprecated)
Updateselectron-updaterManual update checks
SigningCI-integrated code signingUnsigned releases
CSPHTTP headers,
'self'
only
No CSP
Error handlingResult type
{success, data, error}
Raw Error across IPC
Multi-windowMain process as state hubDirect window-to-window
分类推荐避免
安全
contextBridge.exposeInMainWorld()
nodeIntegration: true
IPC
invoke/handle
模式
使用
send/on
处理请求-响应
预加载脚本类型化函数包装器暴露原始
ipcRenderer
构建工具electron-vite基于webpack的工具链
打包Electron Forge手动打包
状态管理Zustand + electron-store简单应用使用Redux
测试Playwright端到端测试Spectron(已废弃)
更新electron-updater手动检查更新
签名CI集成式代码签名未签名的发布包
CSPHTTP头,仅允许
'self'
未设置CSP
错误处理结果类型
{success, data, error}
跨IPC边界传递原始Error
多窗口主进程作为状态中心窗口之间直接通信

Code Generation Guidelines

代码生成指南

When generating Electron code, follow these patterns:
生成Electron代码时,请遵循以下模式:

BrowserWindow Creation

BrowserWindow创建

typescript
const win = new BrowserWindow({
  webPreferences: {
    preload: path.join(__dirname, '../preload/index.js'),
    contextIsolation: true,
    sandbox: true,
    nodeIntegration: false,
  },
});
Always enable contextIsolation and sandbox. Never enable nodeIntegration. The preload path must resolve to the built output location.
typescript
const win = new BrowserWindow({
  webPreferences: {
    preload: path.join(__dirname, '../preload/index.js'),
    contextIsolation: true,
    sandbox: true,
    nodeIntegration: false,
  },
});
始终启用contextIsolation和sandbox。绝不要启用nodeIntegration。预加载脚本路径必须指向构建后的输出位置。

IPC Handler Module

IPC处理器模块

typescript
export function registerFileHandlers(): void {
  ipcMain.handle('save-file', async (_event, content: string) => {
    try {
      await fs.writeFile(filePath, content);
      return { success: true, data: filePath };
    } catch (err) {
      return { success: false, error: (err as Error).message };
    }
  });
}
Group related handlers into modules. Use the result type pattern for all return values. Validate all arguments received from the renderer process.
typescript
export function registerFileHandlers(): void {
  ipcMain.handle('save-file', async (_event, content: string) => {
    try {
      await fs.writeFile(filePath, content);
      return { success: true, data: filePath };
    } catch (err) {
      return { success: false, error: (err as Error).message };
    }
  });
}
将相关处理器分组到模块中。所有返回值均使用结果类型模式。验证所有从渲染进程接收的参数。

Common Anti-Patterns

常见反模式

Avoid these patterns when generating Electron code:
Anti-PatternProblemSolution
nodeIntegration: true
XSS escalates to full RCEKeep disabled (default)
Exposing
ipcRenderer
directly
Full IPC access from rendererWrap in contextBridge functions
Missing
contextIsolation
Renderer accesses preload scopeKeep enabled (default since Electron 12)
No code signingOS security warnings, Gatekeeper blocksSign and notarize for all platforms
BrowserWindow
without sandbox
Preload has full Node.js accessEnable sandbox (default since Electron 20)
Unvalidated IPC argumentsInjection attacks from rendererValidate with Zod or manual checks
0.0.0.0
server binding
Network-exposed local serverAlways bind to
127.0.0.1
Missing CSP headersScript injection vectorsSet strict CSP via HTTP headers
No IPC error serializationLost error context across boundaryUse Result type pattern
Spectron for testingDeprecated, Electron 13 maxUse Playwright
See
references/security/security-checklist.md
for the full security audit checklist.
生成Electron代码时,请避免以下模式:
反模式问题解决方案
nodeIntegration: true
XSS攻击可升级为完全远程代码执行保持禁用(默认配置)
直接暴露
ipcRenderer
渲染进程拥有完整IPC访问权限使用contextBridge包装函数
未启用
contextIsolation
渲染进程可访问预加载脚本作用域保持启用(Electron 12起默认配置)
未进行代码签名操作系统安全警告,Gatekeeper拦截为所有平台进行签名和公证
BrowserWindow
未启用沙箱
预加载脚本拥有完整Node.js权限启用沙箱(Electron 20起默认配置)
IPC参数未验证渲染进程注入攻击使用Zod或手动检查进行验证
绑定到
0.0.0.0
服务器
本地服务器暴露到网络始终绑定到
127.0.0.1
缺少CSP头脚本注入风险通过HTTP头设置严格的CSP
IPC错误未序列化跨边界丢失错误上下文使用结果类型模式
使用Spectron测试已废弃,最高支持Electron 13使用Playwright
完整的安全审计清单请参见
references/security/security-checklist.md

Scripts Reference

脚本参考

analyze-security.ts

analyze-security.ts

Analyze Electron projects for security misconfigurations:
bash
deno run --allow-read scripts/analyze-security.ts <path> [options]

Options:
  --strict    Enable all checks
  --json      Output JSON for CI
  -h, --help  Show help

Examples:
  # Analyze a project
  deno run --allow-read scripts/analyze-security.ts ./src

  # Strict mode for CI pipeline
  deno run --allow-read scripts/analyze-security.ts ./src --strict --json
分析Electron项目的安全配置错误:
bash
deno run --allow-read scripts/analyze-security.ts <path> [options]

选项:
  --strict    启用所有检查
  --json      输出JSON格式用于CI
  -h, --help  显示帮助信息

示例:
  # 分析项目
  deno run --allow-read scripts/analyze-security.ts ./src

  # CI流水线使用严格模式
  deno run --allow-read scripts/analyze-security.ts ./src --strict --json

scaffold-electron-app.ts

scaffold-electron-app.ts

Scaffold a new Electron + React project with secure defaults:
bash
deno run --allow-read --allow-write scripts/scaffold-electron-app.ts [options]

Options:
  --name <name>     App name (required)
  --path <path>     Target directory (default: ./)
  --with-react      Include React setup
  --with-trpc       Include electron-trpc
  --with-tests      Include Playwright tests

Examples:
  # Basic app with React
  deno run --allow-read --allow-write scripts/scaffold-electron-app.ts \
    --name "my-app" --with-react

  # Full setup with trpc and tests
  deno run --allow-read --allow-write scripts/scaffold-electron-app.ts \
    --name "my-app" --with-react --with-trpc --with-tests
使用安全默认配置搭建新的Electron + React项目:
bash
deno run --allow-read --allow-write scripts/scaffold-electron-app.ts [options]

选项:
  --name <name>     应用名称(必填)
  --path <path>     目标目录(默认: ./)
  --with-react      包含React搭建
  --with-trpc       包含electron-trpc
  --with-tests      包含Playwright测试

示例:
  # 带React的基础应用
  deno run --allow-read --allow-write scripts/scaffold-electron-app.ts \
    --name "my-app" --with-react

  # 包含trpc和测试的完整搭建
  deno run --allow-read --allow-write scripts/scaffold-electron-app.ts \
    --name "my-app" --with-react --with-trpc --with-tests

generate-ipc-types.ts

generate-ipc-types.ts

Generate TypeScript type definitions from IPC handler files:
bash
deno run --allow-read --allow-write scripts/generate-ipc-types.ts [options]

Options:
  --handlers <path>  Path to IPC handler files
  --output <path>    Output path for type definitions
  --validate         Validate existing types match handlers

Examples:
  # Generate types from handlers
  deno run --allow-read --allow-write scripts/generate-ipc-types.ts \
    --handlers ./src/main/ipc --output ./src/preload/ipc-types.d.ts

  # Validate types in CI
  deno run --allow-read scripts/generate-ipc-types.ts \
    --handlers ./src/main/ipc --validate
从IPC处理器文件生成TypeScript类型定义:
bash
deno run --allow-read --allow-write scripts/generate-ipc-types.ts [options]

选项:
  --handlers <path>  IPC处理器文件路径
  --output <path>    类型定义输出路径
  --validate         验证现有类型是否匹配处理器

示例:
  # 从处理器生成类型
  deno run --allow-read --allow-write scripts/generate-ipc-types.ts \
    --handlers ./src/main/ipc --output ./src/preload/ipc-types.d.ts

  # CI中验证类型
  deno run --allow-read scripts/generate-ipc-types.ts \
    --handlers ./src/main/ipc --validate

Additional Resources

额外资源

Security

安全

  • references/security/context-isolation.md
    - contextBridge and isolation patterns
  • references/security/csp-and-permissions.md
    - Content Security Policy configuration
  • references/security/security-checklist.md
    - Full security audit checklist
  • references/security/context-isolation.md
    - contextBridge与隔离模式
  • references/security/csp-and-permissions.md
    - 内容安全策略配置
  • references/security/security-checklist.md
    - 完整安全审计清单

IPC Communication

IPC通信

  • references/ipc/typed-ipc.md
    - Typed channel map patterns
  • references/ipc/electron-trpc.md
    - tRPC integration for full type safety
  • references/ipc/error-serialization.md
    - Result types across IPC boundary
  • references/ipc/typed-ipc.md
    - 类型化通道映射模式
  • references/ipc/electron-trpc.md
    - 集成tRPC实现完整类型安全
  • references/ipc/error-serialization.md
    - 跨IPC边界的结果类型

Architecture

架构

  • references/architecture/project-structure.md
    - Directory organization
  • references/architecture/process-separation.md
    - Main, preload, and renderer roles
  • references/architecture/multi-window-state.md
    - Shared state across windows
  • references/architecture/project-structure.md
    - 目录组织
  • references/architecture/process-separation.md
    - 主进程、预加载脚本和渲染进程的角色
  • references/architecture/multi-window-state.md
    - 多窗口共享状态

React Integration

React集成

  • references/integration/react-patterns.md
    - useEffect cleanup, Strict Mode
  • references/integration/state-management.md
    - Zustand and electron-store patterns
  • references/integration/react-patterns.md
    - useEffect清理、严格模式
  • references/integration/state-management.md
    - Zustand与electron-store模式

Packaging & Distribution

打包与分发

  • references/packaging/code-signing.md
    - Platform-specific signing workflows
  • references/packaging/auto-updates.md
    - electron-updater configuration
  • references/packaging/bundle-optimization.md
    - Size reduction techniques
  • references/packaging/ci-cd-patterns.md
    - GitHub Actions matrix builds
  • references/packaging/code-signing.md
    - 平台专属签名工作流
  • references/packaging/auto-updates.md
    - electron-updater配置
  • references/packaging/bundle-optimization.md
    - 包体积缩减技巧
  • references/packaging/ci-cd-patterns.md
    - GitHub Actions矩阵构建

Testing

测试

  • references/testing/playwright-e2e.md
    - Playwright Electron support
  • references/testing/unit-testing.md
    - Jest/Vitest multi-project configuration
  • references/testing/test-structure.md
    - Test organization patterns
  • references/testing/playwright-e2e.md
    - Playwright Electron支持
  • references/testing/unit-testing.md
    - Jest/Vitest多项目配置
  • references/testing/test-structure.md
    - 测试组织模式

Tooling

工具

  • references/tooling/electron-vite.md
    - Build tool configuration
  • references/tooling/electron-forge.md
    - Packaging and distribution
  • references/tooling/tauri-comparison.md
    - When to choose Tauri instead
  • references/tooling/electron-vite.md
    - 构建工具配置
  • references/tooling/electron-forge.md
    - 打包与分发
  • references/tooling/tauri-comparison.md
    - 何时选择Tauri替代方案

Templates

模板

  • assets/templates/main-process.ts.md
    - Main process starter template
  • assets/templates/preload-script.ts.md
    - Preload script with contextBridge
  • assets/templates/ipc-handler.ts.md
    - IPC handler module template
  • assets/templates/react-root.tsx.md
    - React root component template
  • assets/templates/main-process.ts.md
    - 主进程启动模板
  • assets/templates/preload-script.ts.md
    - 带contextBridge的预加载脚本
  • assets/templates/ipc-handler.ts.md
    - IPC处理器模块模板
  • assets/templates/react-root.tsx.md
    - React根组件模板

Configuration Examples

配置示例

  • assets/configs/electron-vite.config.ts.md
    - electron-vite configuration
  • assets/configs/forge.config.js.md
    - Electron Forge configuration
  • assets/configs/tsconfig.json.md
    - TypeScript configuration presets
  • assets/configs/playwright.config.ts.md
    - Playwright Electron test config
  • assets/configs/electron-vite.config.ts.md
    - electron-vite配置
  • assets/configs/forge.config.js.md
    - Electron Forge配置
  • assets/configs/tsconfig.json.md
    - TypeScript配置预设
  • assets/configs/playwright.config.ts.md
    - Playwright Electron测试配置

Complete Examples

完整示例

  • assets/examples/typed-ipc-example.md
    - End-to-end typed IPC walkthrough
  • assets/examples/multi-window-example.md
    - Multi-window state management
  • assets/examples/typed-ipc-example.md
    - 端到端类型化IPC演练
  • assets/examples/multi-window-example.md
    - 多窗口状态管理