mcpField
E
electron-best-practices

electron-best-practices

github.com/ninjasln-labs開発451 回インストール3 週間前に更新
リポジトリ

electron-best-practices について

React で Electron アプリを開発する開発者やエージェント向けのスキルです。安全な設計、型安全な IPC、プロジェクト設定、パッケージ化、署名、テストを扱い、セキュリティ分析やスキャフォールド、IPC 型生成のスクリプトも含みます。

主な機能

  1. 01contextBridge とサンドボックスの安全パターン
  2. 02型安全な IPC 通信パターン
  3. 03electron-vite と Electron Forge の設定
  4. 04パッケージ化、コード署名、公証のガイダンス
  5. 05セキュリティ分析、スキャフォールド、型生成スクリプト
  6. 06Playwright と単体テストのガイダンス

活用シーン

  1. 01Electron + React アプリのひな型作成
  2. 02メインプロセスとレンダラープロセス間の通信実装
  3. 03Electron プロジェクトのセキュリティ設定の監査
  4. 04デスクトップアプリのパッケージ化と署名の準備
  5. 05Electron アプリのエンドツーエンドテスト作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/ninjasln-labs/agent-skills --skill electron-best-practices

インストール後、Claude Code で/electron-best-practicesを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/configs/
electron-vite.config.ts.md
forge.config.js.md
playwright.config.ts.md
tsconfig.json.md
assets/examples/
multi-window-example.md
typed-ipc-example.md
assets/templates/
ipc-handler.ts.md
main-process.ts.md
preload-script.ts.md
react-root.tsx.md
references/architecture/
multi-window-state.md
process-separation.md
project-structure.md
references/integration/
react-patterns.md
state-management.md
references/ipc/
electron-trpc.md
error-serialization.md
typed-ipc.md
references/packaging/
auto-updates.md
bundle-optimization.md
ci-cd-patterns.md
code-signing.md
references/security/
context-isolation.md
csp-and-permissions.md
security-checklist.md
references/testing/
playwright-e2e.md
test-structure.md
unit-testing.md
references/tooling/
electron-forge.md
electron-vite.md

詳細

Electron + React のベストプラクティス

中文クイックガイド(クイックガイド)

  • できること:React を使った Electron アプリ開発におけるセキュリティ、型安全な IPC、プロセス連携、パッケージ化・署名・公証、テストのパターンを示し、分析、スキャフォールディング生成、型生成のための参考資料を提供します。
  • 利用する場面:メイン/preload/レンダラープロセスのコード作成、electron-vite または Forge の設定、IPC の構築、contextBridge/sandbox/CSP によるセキュリティ対策、署名・公証、Playwright を使った Electron アプリのテストを行うときに利用します。Tauri、純粋な Web アプリ、Electron 20 未満のバージョン、React 以外のレンダラーフレームワークには使用しません。
  • 基本手順:①まず安全なデフォルト設定を適用します(contextIsolation、sandbox、nodeIntegration の無効化、メインプロセスとレンダラープロセス間の通信はすべて contextBridge 経由にする)。②references/ からパターンを選びます(型付き IPC、プロセス分離、React 連携)。③electron-vite または Forge でパッケージ化し、コード署名/公証を行います。④Playwright によるエンドツーエンドテストと Jest/Vitest による単体テストで検証します。
  • 中国国内からのアクセス性:パターン、参考資料、テンプレートはすべてこのパッケージ内(references/、assets/templates/)に含まれており、ネット接続なしで利用できます。本文に記載されている任意の作業には外部環境が必要です。具体的には、GitHub Actions のマトリックスビルドと、deno run による scripts/ 配下の便利なスクリプトの実行です。利用できない場合は、本文に記載された確認可能な出力をもとに対応し、実行できなかった手順を明示してください。

AI エージェントが React を使って安全で本番運用に対応できる Electron アプリを構築できるよう支援します。このスキルでは、セキュリティパターン、型安全な IPC 通信、プロジェクト設定のガイダンス、パッケージ化とコード署名のワークフローに加え、分析、スキャフォールディング、型生成のためのツールを提供します。

このスキルを使用する場面

次のような場合にこのスキルを使用してください:

  • Electron のメイン、preload、またはレンダラープロセスのコードを生成するとき
  • electron-vite または Electron Forge を設定するとき
  • プロセス間の IPC 通信を設定するとき
  • セキュリティパターン(contextBridge、sandbox、CSP)を実装するとき
  • デスクトップアプリをパッケージ化、署名、公証するとき
  • Playwright で Electron アプリをテストするとき
  • マルチウィンドウのアーキテクチャを設計するとき

次の場合、このスキルは使用しないでください:

  • Tauri アプリを構築するとき(仕組みが異なるため、Tauri 固有のガイダンスを使用してください)
  • デスクトップ向けの要件がない純粋な Web アプリを構築するとき
  • Electron 20 未満のバージョンを対象とするとき(セキュリティのデフォルト設定が異なります)
  • React 以外のレンダラーフレームワークを使用するとき(フレームワーク固有のスキルを使用してください)

基本原則

1. セキュリティを最優先するアーキテクチャ

最新の Electron では、Electron 20 以降で標準となった 3 つのデフォルト設定がセキュリティの要となります。context isolation、sandbox モード、nodeIntegration の無効化です。いずれかを無効にすると、XSS 攻撃によって完全なリモートコード実行に発展する可能性があります。メインプロセスとレンダラープロセス間の通信は、すべて contextBridge 経由にする必要があります。

// 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);
  }
});

ローカルファイルを読み込むアプリでは、HTTP ヘッダーで Content Security Policy を設定し、スクリプトのソースを 'self' に制限してください。

2. 型安全な IPC 通信

リクエストとレスポンスの通信には、send/on より invoke/handle パターンを推奨します。適切な async/await のセマンティクスとエラー伝播が得られます。型付きチャンネルには、次のマップ型パターンを使用してください。

type IpcChannelMap = {
  'load-prefs': { args: []; return: UserPreferences };
  'save-file': { args: [content: string]; return: { success: boolean } };
};

複雑なアプリケーションでは、electron-trpc を使うと、tRPC のルーターパターンと Zod による検証を利用した完全な型安全性を実現できます。

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. 最新のプロジェクト設定

推奨スタックでは、開発に electron-vite、パッケージ化に Electron Forge を使用します。electron-vite は、メイン、preload、レンダラープロセスを一元管理する統合設定を提供し、1 秒未満での開発サーバー起動と即時の HMR を実現します。Electron Forge は、署名と公証に Electron のファーストパーティパッケージを使用します。

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
4. React 連携パターン

React 18 の並行処理機能は、Electron の Chromium ベースのレンダラーでも通常どおり動作します。Strict Mode ではエフェクトが二重に呼び出されるため、メモリーの問題につながる IPC リスナーのリークを検出できます。IPC リスナーを登録するエフェクトからは、必ずクリーンアップ関数を返してください。

useEffect(() => {
  const cleanup = window.electronAPI.onUpdateCounter((value) => {
    setCount(value);
  });
  return cleanup;
}, []);

マルチウィンドウアプリケーションでは、共有状態の単一の信頼できる情報源としてメインプロセスを使用してください。electron-store による永続化と IPC ブロードキャストを組み合わせれば、どのウィンドウで変更しても、ほかのすべてのウィンドウに反映されます。

クイックリファレンス

カテゴリ推奨避ける
セキュリティcontextBridge.exposeInMainWorld()nodeIntegration: true
IPCinvoke/handle パターンリクエストとレスポンスに send/on を使用する
プリロード型付き関数ラッパー生の ipcRenderer を公開する
ビルドツールelectron-vitewebpack ベースのツールチェーン
パッケージングElectron Forge手動でのパッケージング
状態管理Zustand + electron-storeシンプルなアプリで Redux を使用する
テストPlaywright E2ESpectron(非推奨)
アップデートelectron-updaterアップデートを手動で確認する
署名CI 統合型のコード署名署名なしのリリース
CSPHTTP ヘッダーで 'self' のみCSP を設定しない
エラー処理結果型 {success, data, error}IPC 経由で生の Error を渡す
マルチウィンドウメインプロセスを状態ハブにするウィンドウ間で直接やり取りする

コード生成ガイドライン

Electron コードを生成する際は、次のパターンに従ってください。

BrowserWindow の作成
const win = new BrowserWindow({
  webPreferences: {
    preload: path.join(__dirname, '../preload/index.js'),
    contextIsolation: true,
    sandbox: true,
    nodeIntegration: false,
  },
});

contextIsolation と sandbox は常に有効にしてください。nodeIntegration は絶対に有効にしないでください。プリロードのパスは、ビルド済みの出力先を指すようにしてください。

IPC ハンドラーモジュール
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 };
    }
  });
}

関連するハンドラーはモジュールにまとめてください。すべての戻り値に結果型パターンを使用してください。レンダラープロセスから受け取るすべての引数を検証してください。

よくあるアンチパターン

Electron コードを生成する際は、次のパターンを避けてください。

アンチパターン問題解決策
nodeIntegration: trueXSS が完全な RCE に発展する無効のままにする(デフォルト)
ipcRenderer を直接公開するレンダラーから IPC に完全にアクセスできるcontextBridge 関数でラップする
contextIsolation がないレンダラーからプリロードのスコープにアクセスできる有効のままにする(Electron 12 以降のデフォルト)
コード署名がないOS のセキュリティ警告が表示され、Gatekeeper にブロックされるすべてのプラットフォーム向けに署名し、公証する
sandbox のない BrowserWindowプリロードから Node.js に完全にアクセスできるsandbox を有効にする(Electron 20 以降のデフォルト)
検証されていない IPC 引数レンダラーからのインジェクション攻撃Zod または手動チェックで検証する
0.0.0.0 へのサーバーバインドローカルサーバーがネットワークに公開される常に 127.0.0.1 にバインドする
CSP ヘッダーがないスクリプトインジェクションの攻撃経路になるHTTP ヘッダーで厳格な CSP を設定する
IPC エラーのシリアライズがない境界を越える際にエラーのコンテキストが失われる結果型パターンを使用する
テストに Spectron を使用する非推奨で、対応する Electron は最大 13Playwright を使用する

セキュリティ監査チェックリストの全文は references/security/security-checklist.md を参照してください。

スクリプトリファレンス

analyze-security.ts

Electron プロジェクトのセキュリティ設定ミスを分析します。

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
scaffold-electron-app.ts

安全なデフォルト設定を備えた、新しい Electron + React プロジェクトをスキャフォールドします。

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
generate-ipc-types.ts

IPC ハンドラーファイルから TypeScript 型定義を生成します。

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

追加リソース

セキュリティ
  • references/security/context-isolation.md - contextBridge と分離のパターン
  • references/security/csp-and-permissions.md - コンテンツセキュリティポリシーの設定
  • references/security/security-checklist.md - セキュリティ監査チェックリストの全文
IPC 通信
  • references/ipc/typed-ipc.md - 型付きチャネルマップのパターン
  • references/ipc/electron-trpc.md - 完全な型安全性を実現する tRPC 統合
  • references/ipc/error-serialization.md - IPC 境界を越える結果型
アーキテクチャ
  • references/architecture/project-structure.md - ディレクトリ構成
  • references/architecture/process-separation.md - メイン、プリロード、レンダラーの役割
  • references/architecture/multi-window-state.md - ウィンドウ間での状態共有
React 統合
  • references/integration/react-patterns.md - useEffect のクリーンアップ、Strict Mode
  • references/integration/state-management.md - Zustand と electron-store のパターン
パッケージ化と配布
  • 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 のマトリックスビルド
テスト
  • references/testing/playwright-e2e.md - Playwright の Electron サポート
  • references/testing/unit-testing.md - Jest/Vitest のマルチプロジェクト設定
  • references/testing/test-structure.md - テスト構成のパターン
ツール
  • references/tooling/electron-vite.md - ビルドツールの設定
  • references/tooling/electron-forge.md - パッケージ化と配布
  • references/tooling/tauri-comparison.md - Tauri を選ぶ場合
テンプレート
  • 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 ルートコンポーネントのテンプレート
設定例
  • 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 テスト設定
完全な例
  • assets/examples/typed-ipc-example.md - 型付き IPC のエンドツーエンド解説
  • assets/examples/multi-window-example.md - 複数ウィンドウの状態管理

最小限の実例

前提条件: 上記のセキュアなデフォルト設定(contextIsolation: true、sandbox: true、contextBridge を介した preload)を使用する Electron + React アプリです。

呼び出し:「レンダラーからファイルを保存できるようにし、エラーを握りつぶさずにユーザーに表示してください。」

結果の抜粋(メインプロセスで登録 → preload で公開 → レンダラーで呼び出し、エラー状態を表示):

// src/main/ipc/save-file.ts — main process registers the handler
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 };
  }
});
// src/preload/index.ts — preload exposes exactly this one function
contextBridge.exposeInMainWorld('electronAPI', {
  saveFile: (content: string) => ipcRenderer.invoke('save-file', content),
});
// renderer — invoke, then map the Result type to a user-visible state
async function handleSave(content: string) {
  const result = await window.electronAPI.saveFile(content);
  if (!result.success) {
    setStatus({ kind: 'error', message: `Couldn't save file: ${result.error}` });
    return;
  }
  setStatus({ kind: 'saved', path: result.data });
}

ハンドラーは拒否を生の Error として外部に伝播させません。Result 型が境界を越え、レンダラーは以下の「ユーザーへのエラー表示」に従って error を画面に表示される状態へ変換します。

ユーザーへのエラー表示

Result 型のパターンは IPC 境界向けのものです。レンダラーでは、人が対処できる情報を表示する必要があります。コードを生成するときは、次の点に従ってください。

  • すべての IPC 失敗をユーザーに見える状態に変換してください。トリガーとなったコントロール付近にインラインメッセージを表示する(フォーム)、トーストまたはバナーを表示する(バックグラウンド操作)、エラー境界を設ける(レンダリングのクラッシュ)などです。拒否されたプロミスを握りつぶしてはいけません。
  • 「エラーが発生しました」だけでなく、原因と次の手順を示してください。例:Couldn't save file: disk is full. Free up space or choose another location. Result 型の message(この目的で境界を越えているもの)は含めますが、生のスタックトレースは決して表示しません。
  • 再試行可能なエラーと致命的なエラーを区別してください。ネットワークやオフラインの失敗には「再試行」アクションを表示し、権限や検証の失敗には再試行ボタンではなく手順を示してください。
  • 完全なコンテキスト(チャネル名、引数の形状)をメインプロセスのログに記録し、UI には要約したメッセージだけを表示してください。

スクリプトの失敗と終了

同梱されている3つのスクリプトはすべてDenoで実行されます。各失敗には、確認できる症状と終了結果があります。

症状原因対処
command not found: denoDenoがインストールされていませんDenoをインストールする(deno.comを参照)か、手動で進めます。references/とassets/templates/のパターンを手動で適用してください。スクリプトは便利なものであり、必須ではありません。要求されたスキャフォールドや分析を黙って省略しないでください。実行しなかった手順をユーザーに伝えてください。
パスの読み取り時にPermissionDenied--allow-readがありません(スキャフォールド/型生成では--allow-writeも必要です)上記のスクリプトリファレンスに記載されているフラグを付けて再実行してください。これらは文書化されている最小要件です。
analyze-security.tsが--strict --jsonでゼロ以外の終了コードを返すチェックに失敗しました(これはレポートであり、クラッシュではありません)JSON出力は修正すべき検出事項として扱い、環境エラーとは見なさないでください。クラッシュ時には、JSONレポートではなくスタックトレースが出力されます。
generate-ipc-types.ts --validateがゼロ以外の終了コードを返す既存の型定義がハンドラーと一致しなくなっています型を再生成してから、--validateを再実行し、終了コードが0であることを確認してください。
scaffold-electron-app.tsが書き込みを拒否する対象ディレクトリが空ではないか、--nameがありません必須の--nameを指定するか、--pathに空のディレクトリを指定してください。このスクリプトは既存のファイルを上書きしません。
実行時:アプリからのネットワークリクエストが失敗する(タイムアウト/オフライン状態。メインプロセスのログで確認できます)一時的な障害、またはホストに到達できません回数を限定して(例:バックオフを伴って2~3回)再試行し、その後は「ユーザーへのエラーの表示」に従って、再試行アクションのあるユーザーに見えるエラー状態に移行してください。無制限に黙って再試行するループは決して行わないでください。

やってはいけないこと → 解決方法(FAQ)

やってはいけないこと確認できる症状解決方法
「1つのウィンドウだけ」でnodeIntegrationを有効にするレンダラーからrequire()を実行でき、セキュリティチェックリストで警告されます無効のままにし、必要な関数だけをcontextBridge経由で公開してください。
リクエストと応答の呼び出しにsend/onを使う応答が競合しやすく、結果をawaitできませんinvoke/handleを使用してください。
IPC経由でErrorオブジェクトを渡すレンダラーにはメッセージのない{}のようなオブジェクトが届きますResult型{ success, data, error }を返してください。
CSPを設定せずにBrowserWindowでリモートURLを読み込むContent Security Policyのチェックリスト項目に違反しますHTTPヘッダーで厳格なCSPを設定し、ローカルコンテンツでは'self'のみを許可してください。
Spectronでテストする非推奨で、Electron 13までしか対応していませんPlaywrightを使用してください(references/testing/playwright-e2e.md)。
Tauriまたは純粋なWebアプリにこのスキルを使うガイダンスがランタイムに適用されません使用を中止してください。上記の「適用しない場合」の境界で、これらのランタイムについて説明しています。

コメント