electron-best-practices
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseElectron + 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 property of Error objects. Wrap responses in a result type to preserve full error context.
message{ success, data, error }对于请求-响应式通信,推荐使用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.html4. 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
快速参考
| Category | Prefer | Avoid |
|---|---|---|
| Security | | |
| IPC | | |
| Preload | Typed function wrappers | Exposing raw |
| Build tool | electron-vite | webpack-based toolchains |
| Packaging | Electron Forge | Manual packaging |
| State | Zustand + electron-store | Redux for simple apps |
| Testing | Playwright E2E | Spectron (deprecated) |
| Updates | electron-updater | Manual update checks |
| Signing | CI-integrated code signing | Unsigned releases |
| CSP | HTTP headers, | No CSP |
| Error handling | Result type | Raw Error across IPC |
| Multi-window | Main process as state hub | Direct window-to-window |
| 分类 | 推荐 | 避免 |
|---|---|---|
| 安全 | | |
| IPC | | 使用 |
| 预加载脚本 | 类型化函数包装器 | 暴露原始 |
| 构建工具 | electron-vite | 基于webpack的工具链 |
| 打包 | Electron Forge | 手动打包 |
| 状态管理 | Zustand + electron-store | 简单应用使用Redux |
| 测试 | Playwright端到端测试 | Spectron(已废弃) |
| 更新 | electron-updater | 手动检查更新 |
| 签名 | CI集成式代码签名 | 未签名的发布包 |
| CSP | HTTP头,仅允许 | 未设置CSP |
| 错误处理 | 结果类型 | 跨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-Pattern | Problem | Solution |
|---|---|---|
| XSS escalates to full RCE | Keep disabled (default) |
Exposing | Full IPC access from renderer | Wrap in contextBridge functions |
Missing | Renderer accesses preload scope | Keep enabled (default since Electron 12) |
| No code signing | OS security warnings, Gatekeeper blocks | Sign and notarize for all platforms |
| Preload has full Node.js access | Enable sandbox (default since Electron 20) |
| Unvalidated IPC arguments | Injection attacks from renderer | Validate with Zod or manual checks |
| Network-exposed local server | Always bind to |
| Missing CSP headers | Script injection vectors | Set strict CSP via HTTP headers |
| No IPC error serialization | Lost error context across boundary | Use Result type pattern |
| Spectron for testing | Deprecated, Electron 13 max | Use Playwright |
See for the full security audit checklist.
references/security/security-checklist.md生成Electron代码时,请避免以下模式:
| 反模式 | 问题 | 解决方案 |
|---|---|---|
| XSS攻击可升级为完全远程代码执行 | 保持禁用(默认配置) |
直接暴露 | 渲染进程拥有完整IPC访问权限 | 使用contextBridge包装函数 |
未启用 | 渲染进程可访问预加载脚本作用域 | 保持启用(Electron 12起默认配置) |
| 未进行代码签名 | 操作系统安全警告,Gatekeeper拦截 | 为所有平台进行签名和公证 |
| 预加载脚本拥有完整Node.js权限 | 启用沙箱(Electron 20起默认配置) |
| IPC参数未验证 | 渲染进程注入攻击 | 使用Zod或手动检查进行验证 |
绑定到 | 本地服务器暴露到网络 | 始终绑定到 |
| 缺少CSP头 | 脚本注入风险 | 通过HTTP头设置严格的CSP |
| IPC错误未序列化 | 跨边界丢失错误上下文 | 使用结果类型模式 |
| 使用Spectron测试 | 已废弃,最高支持Electron 13 | 使用Playwright |
完整的安全审计清单请参见。
references/security/security-checklist.mdScripts 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 --jsonscaffold-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-testsgenerate-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 --validateAdditional Resources
额外资源
Security
安全
- - contextBridge and isolation patterns
references/security/context-isolation.md - - Content Security Policy configuration
references/security/csp-and-permissions.md - - Full security audit checklist
references/security/security-checklist.md
- - contextBridge与隔离模式
references/security/context-isolation.md - - 内容安全策略配置
references/security/csp-and-permissions.md - - 完整安全审计清单
references/security/security-checklist.md
IPC Communication
IPC通信
- - Typed channel map patterns
references/ipc/typed-ipc.md - - tRPC integration for full type safety
references/ipc/electron-trpc.md - - Result types across IPC boundary
references/ipc/error-serialization.md
- - 类型化通道映射模式
references/ipc/typed-ipc.md - - 集成tRPC实现完整类型安全
references/ipc/electron-trpc.md - - 跨IPC边界的结果类型
references/ipc/error-serialization.md
Architecture
架构
- - Directory organization
references/architecture/project-structure.md - - Main, preload, and renderer roles
references/architecture/process-separation.md - - Shared state across windows
references/architecture/multi-window-state.md
- - 目录组织
references/architecture/project-structure.md - - 主进程、预加载脚本和渲染进程的角色
references/architecture/process-separation.md - - 多窗口共享状态
references/architecture/multi-window-state.md
React Integration
React集成
- - useEffect cleanup, Strict Mode
references/integration/react-patterns.md - - Zustand and electron-store patterns
references/integration/state-management.md
- - useEffect清理、严格模式
references/integration/react-patterns.md - - Zustand与electron-store模式
references/integration/state-management.md
Packaging & Distribution
打包与分发
- - Platform-specific signing workflows
references/packaging/code-signing.md - - electron-updater configuration
references/packaging/auto-updates.md - - Size reduction techniques
references/packaging/bundle-optimization.md - - GitHub Actions matrix builds
references/packaging/ci-cd-patterns.md
- - 平台专属签名工作流
references/packaging/code-signing.md - - electron-updater配置
references/packaging/auto-updates.md - - 包体积缩减技巧
references/packaging/bundle-optimization.md - - GitHub Actions矩阵构建
references/packaging/ci-cd-patterns.md
Testing
测试
- - Playwright Electron support
references/testing/playwright-e2e.md - - Jest/Vitest multi-project configuration
references/testing/unit-testing.md - - Test organization patterns
references/testing/test-structure.md
- - Playwright Electron支持
references/testing/playwright-e2e.md - - Jest/Vitest多项目配置
references/testing/unit-testing.md - - 测试组织模式
references/testing/test-structure.md
Tooling
工具
- - Build tool configuration
references/tooling/electron-vite.md - - Packaging and distribution
references/tooling/electron-forge.md - - When to choose Tauri instead
references/tooling/tauri-comparison.md
- - 构建工具配置
references/tooling/electron-vite.md - - 打包与分发
references/tooling/electron-forge.md - - 何时选择Tauri替代方案
references/tooling/tauri-comparison.md
Templates
模板
- - Main process starter template
assets/templates/main-process.ts.md - - Preload script with contextBridge
assets/templates/preload-script.ts.md - - IPC handler module template
assets/templates/ipc-handler.ts.md - - React root component template
assets/templates/react-root.tsx.md
- - 主进程启动模板
assets/templates/main-process.ts.md - - 带contextBridge的预加载脚本
assets/templates/preload-script.ts.md - - IPC处理器模块模板
assets/templates/ipc-handler.ts.md - - React根组件模板
assets/templates/react-root.tsx.md
Configuration Examples
配置示例
- - electron-vite configuration
assets/configs/electron-vite.config.ts.md - - Electron Forge configuration
assets/configs/forge.config.js.md - - TypeScript configuration presets
assets/configs/tsconfig.json.md - - Playwright Electron test config
assets/configs/playwright.config.ts.md
- - electron-vite配置
assets/configs/electron-vite.config.ts.md - - Electron Forge配置
assets/configs/forge.config.js.md - - TypeScript配置预设
assets/configs/tsconfig.json.md - - Playwright Electron测试配置
assets/configs/playwright.config.ts.md
Complete Examples
完整示例
- - End-to-end typed IPC walkthrough
assets/examples/typed-ipc-example.md - - Multi-window state management
assets/examples/multi-window-example.md
- - 端到端类型化IPC演练
assets/examples/typed-ipc-example.md - - 多窗口状态管理
assets/examples/multi-window-example.md