Learning Record learning from practice

· web

Electron, and What Tonsky's 'Claude is an Electron App' Post Actually Argues

Electron is a framework for building cross-platform desktop apps with HTML, CSS, and JavaScript. VS Code, Slack, Discord, Teams, Notion, and Anthropic’s Claude Desktop are all built on it.

How it actually works

Per Electron’s own process model docs, an Electron app inherits Chromium’s multi-process architecture:

  • Main process — a single Node.js process per app. It creates windows (BrowserWindow), controls the app lifecycle, and is the only place with unrestricted access to Node.js APIs and native desktop features (menus, tray icons, dialogs).
  • Renderer process — one per window (or web embed), responsible for rendering the UI. It behaves like a regular Chromium browser tab and, by default, has no direct access to Node.js APIs.
  • Preload scripts — run in the renderer before the page loads, with access to Node.js. They use contextBridge to selectively expose specific APIs to the renderer, since contextIsolation keeps the two worlds apart by default.
  • Utility process — an optional extra Node.js process for offloading CPU-heavy or crash-prone work outside the main process.

So the “you get a browser plus a Node.js runtime bundled together” description is correct, but it’s not one monolithic blob — it’s the same isolated main/renderer split Chrome itself uses, wired together with an explicit IPC bridge rather than direct OS-native UI toolkits (WinUI, Cocoa, GTK).

The debate this post is actually about

The article being discussed is Niki Tonsky’s Claude is an Electron App because we’ve lost native, written in response to Drew Breunig’s Why is Claude an Electron App?.

Breunig’s framing: Anthropic’s coding agents can generate a Rust C compiler, so why does Claude Desktop still ship as an Electron app instead of native code per platform? His answer is mostly about engineering economics — agents nail ~90% of a rewrite, but the last mile (edge cases, 3x the platform-specific bug surface, ongoing maintenance) is still expensive, so Electron’s “one codebase, ship everywhere” tradeoff still wins today.

Tonsky’s actual argument is different from what it sounds like from the title — he isn’t defending Electron’s bloat or blaming a “lost generation” of native developers. His claim is that native has stopped being a meaningfully better option at all:

  • APIs: native OS APIs are unpleasant to use, which is why Electron won in the first place — and that gap didn’t need LLMs to close.
  • Look and consistency: native UI stopped being consistent too. He points to Apple placing corner radii and traffic-light buttons “by vibes,” not fixed guidelines — so there’s no stable “native look” left to lose.
  • OS integration: deep OS integration (shared file formats, native calendars, etc.) mostly isn’t real in practice anymore — most services moved to the web, and it’s often easier to integrate on the web than natively.
  • Performance: this is the key point — he argues bloat is a choice, not a property of the web stack. Quoting him directly: “There’s no technical reason why Slack needs to load 80 MiB just to show 10 channel names and 3 messages on a screen. The web is not the problem here! It’s a choice to be bad.”

His backing data for that last point comes from his own earlier JavaScript Bloat in 2024 measurements — pure JS payload size, no images/CSS: Wikipedia loads in 0.2 MB, but Slack ships 55 MB of JavaScript for a chat app, and Jira nearly 50 MB. Meanwhile FastMail (2 MB) does the same job as Gmail (20 MB) at a tenth of the size. Same web platform, wildly different discipline.

His conclusion: rewriting Slack in SwiftUI wouldn’t fix anything by itself, because “the real problem is a lack of care. And the slop; you can build it with any stack.”

Takeaway

Electron itself is just Chromium + Node.js glued together with an IPC bridge instead of native UI toolkits — that part of the common description is accurate. But the widely-shared “Electron = bloat, native = lost craftsmanship” reading of Tonsky’s post inverts his actual point: he thinks native lost its edge on APIs, consistency, and OS integration on its own merits, and that JS bloat is a discipline problem visible in his own byte-for-byte measurements, not something inherent to shipping on the web.

References