Electron

Electron packages a web app with Chromium and Node.js into a desktop application — one codebase shipping to Windows, macOS, and Linux with full OS access. VS Code, Slack, Discord, Figma's desktop app, 1Password, Notion, WhatsApp Desktop: a striking share of the software on your machine is a web app in an Electron shell.

The trade is famous in both directions: your web team ships desktop software with native menus, file access, and auto-update — and every app carries its own ~100+ MB browser and Node runtime, with the memory bill to match. That trade-off (and the rise of Tauri, which swaps bundled Chromium for the OS's webview and a Rust core) defines the modern decision space for desktop-from-web.

TL;DR

Quick Example

The canonical minimal app — main process, secure preload bridge, renderer:

The renderer never sees fs or require — it sees window.api.openFile(). That shape is Electron security.

Core Concepts

Main vs Renderer

The division of labor rule: renderers render; main does everything privileged. Heavy CPU work belongs in neither — use a worker thread or utilityProcess, or the UI (main and renderers block on a busy main process) stutters.

The Security Model

An Electron app is a browser where XSS can become remote code execution on the user's machine — if you've wired it badly. The modern defaults exist for that reason:

Ship It: Packaging, Signing, Updates

The unglamorous half that dominates real Electron work:

Performance as a Practice

The gap between "Electron is bloated" and VS Code is engineering:

Electron vs Tauri (and the Field)

The decision usually reduces to: rendering consistency and JS-everywhere (Electron) vs footprint and Rust-grade native layer (Tauri). Cross-platform webview differences are Tauri's real tax — you're back to testing three browser engines, which Electron's bundling specifically abolished. Adjacent options: Wails (Go + webview, Tauri-shaped), Flutter desktop and .NET MAUI (non-web UI stacks), and PWAs (installable web apps) when you don't actually need deep OS integration — always worth asking first.

Common Mistakes

nodeIntegration: true to "Make It Work"

The classic shortcut that turns any renderer XSS into arbitrary code execution. The preload/contextBridge pattern exists precisely so you never do this — if a library demands it, the library is the problem.

Exposing Generic IPC Power

contextBridge.exposeInMainWorld("ipc", ipcRenderer) (or an invoke(anyChannel, anyArgs) passthrough) recreates the hole with extra steps. Expose named, purpose-specific, input-validated functions.

Blocking the Main Process

Synchronous fs calls, big JSON parses, or heavy computation in main freeze every window's input handling. Main is an event-loop traffic controller — keep it async and thin.

Treating Packaging as a Last-Week Task

Signing certificates, notarization queues, auto-update servers, and per-OS installer quirks reliably consume weeks. Stand up the Forge/CI/signing pipeline in week one with a hello-world build.

Shipping on an Ancient Electron

Old Electron = old Chromium = shipping known-exploitable browser CVEs inside your app. Track supported majors; automate the upgrade PRs.

FAQ

Why do so many companies choose Electron despite the memory cost?

Because the alternative is usually three native teams or no desktop app. One web codebase covering Windows/macOS/Linux (often sharing most code with the web product), hiring from the largest talent pool, and a proven ceiling (VS Code, Figma, Slack) outweigh RAM for most products. Users complain about memory; they buy features.

Electron or Tauri for a new app?

Tauri deserves the default look for new, footprint-sensitive apps — the size/memory win is dramatic, and 2.0 matured it considerably. Electron remains the safer pick when you need pixel-identical rendering across platforms, depend on Chromium-only APIs, want zero Rust, or lean on its deeper ecosystem (auto-update infra, native modules, a decade of Stack Overflow).

Can I reuse my React/Vue web app?

Largely, yes — the renderer is a browser, so your SPA runs nearly unchanged; the work is the desktop layer (menus, IPC-backed features, offline files, updates). Keep web and desktop sharing a core via a monorepo, with platform adapters at the edge.

How do Electron apps talk to the OS?

Through the main process: Electron's own APIs (dialogs, tray, notifications, clipboard, global shortcuts) cover most needs; Node native addons or spawned helpers cover the rest. The renderer always asks via IPC — that boundary is the architecture.

Is Electron dying?

The "bloat" discourse is old; the usage isn't declining — Chromium-based Electron still ships the most-used developer and collaboration tools on desktop, and the project tracks Chromium aggressively. What's changed is real competition (Tauri) finally pressuring the footprint — good news whichever you pick.

Related Topics

References