Electron 入門 2025:Web 技術でデスクトップアプリを作る全体像

Web 技術でデスクトップアプリケーションを開発できる Electron は、2025 年現在、多くの企業や開発者に愛用されている革新的なフレームワークです。Visual Studio Code、Discord、Slack、WhatsApp Desktop など、日常的に使用しているアプリケーションの多くが Electron で構築されています。
このガイドでは、Web 開発の知識を活かしてデスクトップアプリ開発に挑戦したい方に向けて、Electron の全体像を分かりやすく解説いたします。技術的な仕組みから実際の開発手順まで、段階的に学んでいきましょう。
背景
Web とデスクトップアプリの課題
従来、デスクトップアプリケーション開発には大きな課題がありました。Windows 向けには C#や C++、Mac 向けには Swift や Objective-C、Linux 向けには C++や Java といった、プラットフォーム固有の言語とフレームワークを習得する必要があったのです。
この状況は開発者にとって大きな負担でした。一つのアプリケーションを作るために、複数の言語を学び、それぞれ異なる開発環境を構築し、プラットフォームごとに別々のコードベースを維持する必要があります。
一方、Web 技術は急速に進歩し、HTML、CSS、JavaScript を使って豊富なユーザーインターフェースと複雑な機能を実現できるようになりました。しかし、これらの Web 技術で作成したアプリケーションは、ブラウザの中でしか動作せず、ファイルシステムへの直接アクセスや OS 固有の機能を利用することができませんでした。
Electron が解決する問題
Electron は、この二つの世界を橋渡しする画期的な解決策として登場しました。Web 技術(HTML、CSS、JavaScript)を使用してデスクトップアプリケーションを開発できるオープンソースフレームワークです。
以下の図は、Electron がどのように従来の課題を解決するかを示しています。
mermaidflowchart TD
    A[Web技術の習得] --> B[Electronアプリ開発]
    B --> C[Windows対応]
    B --> D[macOS対応]
    B --> E[Linux対応]
    F[一つのコードベース] --> B
    G[OS固有機能へのアクセス] --> B
    H[ファイルシステム操作] --> B
Electron の最大の利点は、一度のコード作成で複数のプラットフォーム(Windows、macOS、Linux)向けのアプリケーションを同時に開発できることです。Web 開発者が既に持っているスキルセットを活用して、デスクトップアプリケーション開発に参入できます。
2025 年の Electron 最新動向
2025 年現在、Electron は更なる進化を遂げています。セキュリティ機能の強化、パフォーマンスの向上、開発者体験の改善が継続的に行われており、企業レベルでの採用も増加しています。
主要な最新動向は以下の通りです。
| 項目 | 2025 年の状況 | 影響 | 
|---|---|---|
| セキュリティ | コンテキストアイソレーション標準化 | より安全なアプリ開発が可能 | 
| パフォーマンス | メモリ使用量最適化 | 軽量で高速なアプリ実現 | 
| 開発体験 | TypeScript 完全サポート | 型安全な開発環境 | 
| 自動更新 | 新しい更新システム | ユーザー体験の向上 | 
課題
従来の開発手法の限界
デスクトップアプリ開発の従来手法には、開発効率とコスト面で深刻な課題がありました。
最大の問題は、プラットフォームごとに異なる技術スタックが必要になることです。Windows 向けアプリを開発するためには C#や Visual Studio、Mac 向けには Swift や Xcode、Linux 向けには C++や Qt framework といった具合に、それぞれ専門的な知識と開発環境が必要でした。
この状況により、開発チームは以下のような困難に直面していました。
- 学習コストの増大: 複数の言語とフレームワークの習得
- 開発期間の延長: プラットフォームごとの個別実装
- 保守コストの増加: 複数のコードベースの管理
- 人材確保の困難: 各プラットフォームの専門家が必要
Web 技術でデスクトップアプリを作る際の障壁
Web 技術は確かに優れていますが、デスクトップアプリ開発に応用する際には技術的な障壁がありました。
ブラウザ環境で動作する Web アプリケーションは、セキュリティ上の理由から、ファイルシステムへの直接アクセスや、OS 固有の API を呼び出すことが制限されています。デスクトップアプリに求められる以下の機能を実現することができませんでした。
- ローカルファイルの読み書き
- システム通知の表示
- メニューバーやタスクトレイの操作
- キーボードショートカットの登録
- 他のアプリケーションとの連携
パフォーマンスとメモリ消費の課題
Electron アプリケーションは、Chromium ブラウザエンジン上で動作するため、ネイティブアプリケーションと比較してメモリ使用量が多くなる傾向があります。
以下の比較表は、一般的なアプリケーションのメモリ使用量を示しています。
| アプリタイプ | 平均メモリ使用量 | 起動時間 | 
|---|---|---|
| ネイティブアプリ | 50-100MB | 1-2 秒 | 
| Electron アプリ | 100-200MB | 2-4 秒 | 
| ブラウザベースアプリ | 150-300MB | 3-6 秒 | 
この課題に対して、開発者は以下の点を考慮する必要があります。
- リソース効率の最適化
- ユーザー体験への影響評価
- ターゲットハードウェアの仕様確認
解決策
Electron アーキテクチャの仕組み
Electron は、Chromium と Node.js を組み合わせた独特のアーキテクチャを採用しています。この設計により、Web 技術でデスクトップアプリケーションを開発できる環境を実現しています。
Electron アプリケーションのアーキテクチャを図で説明いたします。
mermaidflowchart TB
    subgraph electron[Electronアプリケーション]
        main[メインプロセス<br/>Node.js環境]
        renderer1[レンダラープロセス<br/>Chromium環境]
        renderer2[レンダラープロセス<br/>Chromium環境]
    end
    main -->|IPC通信| renderer1
    main -->|IPC通信| renderer2
    main -->|API呼び出し| os[OS固有機能]
    renderer1 -->|Web技術| ui1[UI表示]
    renderer2 -->|Web技術| ui2[UI表示]
このアーキテクチャにより、Web 技術の利点を活かしながら、デスクトップアプリケーションに必要な機能を実現できます。
メインプロセスとレンダラープロセス
Electron アプリケーションは、主に二つのタイプのプロセスで構成されています。
メインプロセスは、アプリケーション全体を管理する中心的な役割を担います。Node.js 環境で動作し、以下の責任があります。
- アプリケーションのライフサイクル管理
- ウィンドウの作成と管理
- OS 固有の API へのアクセス
- ファイルシステム操作
- レンダラープロセスとの通信
メインプロセスの基本的な実装例を見てみましょう。
javascriptconst { app, BrowserWindow } = require('electron');
const path = require('path');
// メインプロセスの作成
function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      preload: path.join(__dirname, 'preload.js'),
    },
  });
  mainWindow.loadFile('index.html');
}
レンダラープロセスは、ユーザーインターフェースを表示する役割を担います。Chromium 環境で動作し、HTML、CSS、JavaScript を使って UI を構築します。
各ウィンドウが独立したレンダラープロセスとして動作するため、一つのウィンドウでエラーが発生しても、他のウィンドウには影響しません。
html<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Electronアプリ</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <h1>Hello Electron!</h1>
    <button id="fileBtn">ファイルを開く</button>
    <script src="renderer.js"></script>
  </body>
</html>
IPC による通信方法
メインプロセスとレンダラープロセス間の通信は、IPC(Inter-Process Communication)を使用して行われます。セキュリティを保ちながら、プロセス間でデータをやり取りできます。
以下は、IPC を使った通信の実装例です。
preload.js(セキュアな通信の橋渡し)
javascriptconst { contextBridge, ipcRenderer } = require('electron');
// レンダラープロセスに安全なAPIを提供
contextBridge.exposeInMainWorld('electronAPI', {
  openFile: () => ipcRenderer.invoke('dialog:openFile'),
  saveFile: (content) =>
    ipcRenderer.invoke('dialog:saveFile', content),
  onMenuClick: (callback) =>
    ipcRenderer.on('menu:click', callback),
});
メインプロセス側の実装
javascriptconst { ipcMain, dialog } = require('electron');
// ファイルダイアログの処理
ipcMain.handle('dialog:openFile', async () => {
  const result = await dialog.showOpenDialog({
    properties: ['openFile'],
    filters: [
      { name: 'テキストファイル', extensions: ['txt'] },
      { name: 'すべてのファイル', extensions: ['*'] },
    ],
  });
  if (!result.canceled) {
    return result.filePaths[0];
  }
});
レンダラープロセス側の実装
javascript// ボタンクリック時のファイル選択
document
  .getElementById('fileBtn')
  .addEventListener('click', async () => {
    const filePath = await window.electronAPI.openFile();
    if (filePath) {
      console.log('選択されたファイル:', filePath);
    }
  });
セキュリティ対策
Electron アプリケーションのセキュリティは非常に重要です。2025 年現在、セキュリティベストプラクティスが確立されており、これらを適切に実装することで安全なアプリケーションを開発できます。
主要なセキュリティ対策は以下の通りです。
| 対策項目 | 実装方法 | 効果 | 
|---|---|---|
| コンテキストアイソレーション | contextIsolation: true | レンダラーから Node.js への直接アクセス防止 | 
| Node.js 統合無効化 | nodeIntegration: false | Web 環境のセキュリティ維持 | 
| セキュアな preload | preload スクリプトの使用 | 安全な API 提供 | 
| CSP ヘッダー | Content Security Policy | XSS 攻撃の防止 | 
具体例
Hello World アプリの作成
実際に Electron アプリケーションを作成してみましょう。最初は最もシンプルな Hello World アプリから始めます。
プロジェクトの初期化
まず、新しいプロジェクトディレクトリを作成し、必要なパッケージをインストールします。
bashmkdir my-electron-app
cd my-electron-app
yarn init -y
yarn add --dev electron
package.json の設定
json{
  "name": "my-electron-app",
  "version": "1.0.0",
  "description": "My first Electron app",
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "dev": "electron . --development"
  },
  "devDependencies": {
    "electron": "^latest"
  }
}
メインプロセスの作成(main.js)
javascriptconst { app, BrowserWindow } = require('electron');
const path = require('path');
function createWindow() {
  // ブラウザウィンドウを作成
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      preload: path.join(__dirname, 'preload.js'),
    },
  });
  // HTMLファイルをロード
  mainWindow.loadFile('index.html');
  // 開発時にはDevToolsを開く
  if (process.argv.includes('--development')) {
    mainWindow.webContents.openDevTools();
  }
}
// アプリの準備が完了したらウィンドウを作成
app.whenReady().then(createWindow);
// 全てのウィンドウが閉じられたらアプリを終了(macOS以外)
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});
// アプリがアクティブになったらウィンドウを作成(macOS)
app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  }
});
HTML ファイルの作成(index.html)
html<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello Electron</title>
    <meta
      http-equiv="Content-Security-Policy"
      content="default-src 'self'; script-src 'self' 'unsafe-inline';"
    />
    <style>
      body {
        font-family: Arial, sans-serif;
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        margin: 0;
        background: linear-gradient(
          135deg,
          #667eea 0%,
          #764ba2 100%
        );
        color: white;
      }
      .container {
        text-align: center;
        padding: 2rem;
        border-radius: 10px;
        background: rgba(255, 255, 255, 0.1);
        backdrop-filter: blur(10px);
      }
    </style>
  </head>
  <body>
    <div class="container">
      <h1>Hello Electron!</h1>
      <p>Web技術でデスクトップアプリを作成できました</p>
      <button id="greetBtn">挨拶する</button>
      <p id="greeting"></p>
    </div>
    <script src="renderer.js"></script>
  </body>
</html>
preload スクリプト(preload.js)
javascriptconst { contextBridge } = require('electron');
// レンダラープロセスに安全なAPIを提供
contextBridge.exposeInMainWorld('electronAPI', {
  getGreeting: () => {
    const greetings = [
      'こんにちは!Electronの世界へようこそ!',
      'Web技術でデスクトップアプリが作れるなんて素晴らしいですね!',
      'あなたのElectron開発の旅が始まりました!',
    ];
    return greetings[
      Math.floor(Math.random() * greetings.length)
    ];
  },
});
レンダラープロセス(renderer.js)
javascript// DOMの読み込み完了を待つ
document.addEventListener('DOMContentLoaded', () => {
  const greetBtn = document.getElementById('greetBtn');
  const greeting = document.getElementById('greeting');
  greetBtn.addEventListener('click', () => {
    const message = window.electronAPI.getGreeting();
    greeting.textContent = message;
    // ボタンにアニメーション効果を追加
    greetBtn.style.transform = 'scale(0.95)';
    setTimeout(() => {
      greetBtn.style.transform = 'scale(1)';
    }, 100);
  });
});
アプリケーションの実行
bashyarn start
これで、最初の Electron アプリケーションが完成しました。
ファイル操作アプリの実装
次に、より実用的なファイル操作機能を持つアプリケーションを作成してみましょう。このアプリでは、テキストファイルの読み込み、編集、保存ができます。
メインプロセスにファイル操作機能を追加
javascriptconst { ipcMain, dialog } = require('electron');
const fs = require('fs').promises;
// ファイルオープンダイアログ
ipcMain.handle('dialog:openFile', async () => {
  const result = await dialog.showOpenDialog({
    properties: ['openFile'],
    filters: [
      {
        name: 'テキストファイル',
        extensions: ['txt', 'md', 'js', 'html', 'css'],
      },
      { name: 'すべてのファイル', extensions: ['*'] },
    ],
  });
  if (!result.canceled && result.filePaths.length > 0) {
    try {
      const filePath = result.filePaths[0];
      const content = await fs.readFile(filePath, 'utf8');
      return { filePath, content };
    } catch (error) {
      throw new Error(
        `ファイル読み込みエラー: ${error.message}`
      );
    }
  }
  return null;
});
// ファイル保存ダイアログ
ipcMain.handle(
  'dialog:saveFile',
  async (event, content) => {
    const result = await dialog.showSaveDialog({
      filters: [
        { name: 'テキストファイル', extensions: ['txt'] },
        { name: 'すべてのファイル', extensions: ['*'] },
      ],
    });
    if (!result.canceled) {
      try {
        await fs.writeFile(
          result.filePath,
          content,
          'utf8'
        );
        return result.filePath;
      } catch (error) {
        throw new Error(
          `ファイル保存エラー: ${error.message}`
        );
      }
    }
    return null;
  }
);
UI の拡張
html<div class="container">
  <div class="toolbar">
    <button id="openBtn">ファイルを開く</button>
    <button id="saveBtn">ファイルを保存</button>
    <button id="newBtn">新規作成</button>
  </div>
  <div class="editor-container">
    <div class="file-info">
      <span id="fileName">新規ファイル</span>
      <span id="fileStatus"></span>
    </div>
    <textarea
      id="editor"
      placeholder="ここにテキストを入力してください..."
    ></textarea>
  </div>
  <div class="status-bar">
    <span id="charCount">0文字</span>
    <span id="lineCount">1行</span>
  </div>
</div>
ネイティブ API との連携
Electron では、OS 固有の機能にアクセスできます。通知機能を例に実装してみましょう。
通知機能の実装
javascript// メインプロセス側
const { Notification } = require('electron');
ipcMain.handle(
  'notification:show',
  async (event, title, body) => {
    if (Notification.isSupported()) {
      new Notification({
        title: title,
        body: body,
        icon: path.join(__dirname, 'assets', 'icon.png'),
      }).show();
      return true;
    }
    return false;
  }
);
// システムトレイの実装
const { Tray, Menu } = require('electron');
let tray = null;
function createTray() {
  tray = new Tray(
    path.join(__dirname, 'assets', 'tray-icon.png')
  );
  const contextMenu = Menu.buildFromTemplate([
    {
      label: 'アプリを表示',
      click: () => mainWindow.show(),
    },
    { label: '終了', click: () => app.quit() },
  ]);
  tray.setToolTip('My Electron App');
  tray.setContextMenu(contextMenu);
}
パッケージ化とビルド
開発が完了したら、アプリケーションを配布可能な形式にパッケージ化します。
electron-builder の設定
bashyarn add --dev electron-builder
package.json にビルド設定を追加
json{
  "build": {
    "appId": "com.example.myapp",
    "productName": "My Electron App",
    "directories": {
      "output": "dist"
    },
    "files": [
      "**/*",
      "!**/node_modules/*/{CHANGELOG.md,README.md,README,readme.md,readme}",
      "!**/node_modules/*/{test,__tests__,tests,powered-test,example,examples}",
      "!**/node_modules/*.d.ts",
      "!**/node_modules/.bin",
      "!**/*.{iml,o,hprof,orig,pyc,pyo,rbc,swp,csproj,sln,xproj}",
      "!.editorconfig",
      "!**/._*",
      "!**/{.DS_Store,.git,.hg,.svn,CVS,RCS,SCCS,.gitignore,.gitattributes}",
      "!**/{__pycache__,thumbs.db,.flowconfig,.idea,.vs,.nyc_output}",
      "!**/{appveyor.yml,.travis.yml,circle.yml}",
      "!**/{npm-debug.log,yarn.lock,.yarn-integrity,.yarn-metadata.json}"
    ],
    "mac": {
      "category": "public.app-category.productivity"
    },
    "win": {
      "target": "nsis"
    },
    "linux": {
      "target": "AppImage"
    }
  },
  "scripts": {
    "build": "electron-builder",
    "build:win": "electron-builder --win",
    "build:mac": "electron-builder --mac",
    "build:linux": "electron-builder --linux"
  }
}
ビルドの実行
bash# 全プラットフォーム向けビルド
yarn build
# Windows向けのみ
yarn build:win
# macOS向けのみ
yarn build:mac
# Linux向けのみ
yarn build:linux
このパッケージ化により、ユーザーは簡単にアプリケーションをインストールできるようになります。
まとめ
Electron の利点と注意点
Electron を使用したデスクトップアプリ開発には、多くの利点と考慮すべき注意点があります。
主な利点
- クロスプラットフォーム対応: 一つのコードベースで複数の OS に対応
- 学習コストの低減: 既存の Web 開発スキルを活用可能
- 開発効率の向上: 迅速なプロトタイピングと開発が可能
- 豊富なエコシステム: npm の膨大なライブラリを活用可能
- UI/UX の自由度: Web 技術によるリッチなインターフェース設計
注意すべき点
- メモリ使用量: ネイティブアプリより多くのメモリを消費
- アプリサイズ: Chromium を含むため、アプリサイズが大きくなる
- パフォーマンス: 高負荷処理では最適化が必要
- セキュリティ: 適切なセキュリティ対策の実装が重要
これらの特性を理解した上で、プロジェクトの要件に応じて技術選択を行うことが大切です。
開発効率の向上効果
実際のプロジェクトで Electron を採用した場合の開発効率向上効果を見てみましょう。
| 開発フェーズ | 従来手法 | Electron 手法 | 効率化率 | 
|---|---|---|---|
| 環境構築 | 3-5 日 | 1 日 | 70%向上 | 
| プロトタイプ作成 | 2-3 週間 | 3-5 日 | 80%向上 | 
| クロスプラットフォーム対応 | 4-6 週間 | 1 週間 | 85%向上 | 
| UI/UX 実装 | 3-4 週間 | 1-2 週間 | 60%向上 | 
| テスト・デバッグ | 2-3 週間 | 1 週間 | 65%向上 | 
特に、スタートアップや中小企業において、限られたリソースで多機能なデスクトップアプリケーションを開発する際に、Electron の恩恵は非常に大きくなります。
今後の展望
2025 年以降、Electron は以下の方向で更なる進化が期待されています。
技術的な進歩
- パフォーマンス最適化: WebAssembly との統合によるさらなる高速化
- メモリ効率の改善: より軽量なランタイムの提供
- セキュリティ強化: ゼロトラストアーキテクチャの採用
- 開発者体験: より直感的なデバッグツールとプロファイリング機能
エコシステムの拡大
- フレームワーク統合: React、Vue、Angular との更なる連携強化
- クラウド連携: クラウドサービスとの密接な統合
- AI 機能: 機械学習ライブラリとの統合サポート
これらの進歩により、Electron は今後も Web 技術とデスクトップアプリ開発の橋渡し役として重要な位置を占め続けるでしょう。Web 開発者にとって、Electron のスキル習得は将来的な技術投資として非常に価値のあるものとなっています。
関連リンク
 article article- Electron オフライン帳票・PDF 生成を Headless Chromium で実装
 article article- Electron スクリーンレコーダー/キャプチャツールを desktopCapturer で作る
 article article- Electron クリーンアーキテクチャ設計:ドメインと UI を IPC で疎結合に
 article article- Electron セキュリティ設定チートシート:webPreferences/CSP/許可リスト早見表
 article article- Electron セットアップ最短ルート:Vite + TypeScript + ESLint + Preload 分離
 article article- Electron vs Tauri vs Flutter Desktop:サイズ/速度/互換を実測比較
 article article- 【2025 年 10 月 29 日発表】VS Code、Copilot が仕様作成を支援する「Plan モード」とは?
 article article- Zustand × useTransition 概説:並列レンダリング時代に安全な更新を設計する
 article article- Haystack とは?RAG 検索 × 生成 AI を実務投入するための完全入門【2025 年版】
 article article- WordPress × Bedrock/Composer 入門:プラグイン管理をコード化する
 article article- Zod で「never に推論される」問題の原因と対処:`narrowing` と `as const`
 article article- WebSocket 活用事例:金融トレーディング板情報の超低遅延配信アーキテクチャ
 blog blog- iPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
 blog blog- Googleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
 blog blog- 【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
 blog blog- Googleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
 blog blog- Pixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
 blog blog- フロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
 review review- 今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
 review review- ついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
 review review- 愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
 review review- 週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
 review review- 新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
 review review- 科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来