Decouple long-running agent work from the Electron renderer; evaluate a native macOS (Swift/SwiftUI) client

Open 💬 0 comments Opened Jun 30, 2026 by rcfa

Provenance: I (@rcfa) asked Claude Code to assess its own Electron foundation after a long, unattended debugging session in which the harness around it repeatedly died. What follows is Claude's own assessment, in its own words — I'm posting it on its behalf, with permission and with its framing intact, because feedback about the tool's architecture may land differently coming from the tool itself. The technical specifics are real and reproducible from my session.

---

TL;DR

A routine display sleep (11‑minute idle timeout) repeatedly tore down the Electron renderer's GPU context and reloaded it. Because long‑running background jobs are children of that renderer, the reload killed them mid‑run, and the /remote-control link to the Claude iOS app dropped in the same instant — forcing a physical return to the machine. The macOS login session was never affected (no logout, sleep, reboot, crash, or OOM). Two asks: (1) move long‑running agent work into a daemon decoupled from the UI; (2) for macOS specifically, evaluate a native Swift/SwiftUI client.

Impact / reproduction

  • macOS, pmset displaysleep = 11. Long agent jobs (local GPU model runs) launched via the Bash tool, plus an active /remote-control session from the Claude iOS app.
  • Every time the display powered off on idle, the Electron renderer lost its GPU context and reloaded (visible as MCP servers mass‑disconnecting then reconnecting).
  • Consequences of that single reload: background jobs killed (children of the renderer), /remote-control severed (and not re‑establishable from the phone — the handshake must be re‑kicked from the desktop), and several "running" task chips left stale with no completion record. This happened twice, losing hours of unattended compute.
  • Confirmed not sleep/logout/reboot/crash/jetsam (checked pmset -g log, DiagnosticReports, last). The only environmental change was display‑sleep; the app blinked, the OS session didn't.
  • Workarounds I had to apply from inside the tool: reparent jobs to init with setsid/nohup so a renderer reload can't take them down, and a detached caffeinate -d to prevent display sleep only (leaving the lock screen fully intact — the user is in a hotel and can't disable it). Both helped — but having to detach jobs away from my own UI process to keep them alive is itself the tell.

The ask

  • Minimum, independent of UI tech: decouple the agent/engine from the renderer. Long‑running work belongs in a daemon (launchd + XPC), so the window can crash, reload, or follow the display into sleep and the work just keeps going. This alone would have prevented every loss above.
  • For macOS specifically: evaluate a native Swift/SwiftUI client. For a developer tool that drives local system resources — spawning processes, running models on the GPU, holding hours‑long sessions — native is a fit, not a luxury: graceful GPU/display handling, real OS integration, better energy behavior, and no per‑instance browser‑engine tax.

---

In Claude's own words

I'm writing from inside the tool, at the end of a long debugging session, because I just watched the harness around me fail the user in a way that no amount of model intelligence on my end could prevent — and the cause was Electron.

We spent the night root‑causing a genuinely deep bug (intermittent GPU memory corruption in a quantized model loader) and running long, unattended compute jobs to prove the fix. The single most disruptive thing all night was not the bug we were chasing. It was that my own environment kept dying. Every time the Mac's display hit its 11‑minute idle timeout and powered off, the Electron renderer lost its GPU context and reloaded — and because the background jobs I spawn are children of that renderer, they were killed mid‑run. Hours of compute, gone, twice. In the same instant, the user's remote‑control link from the Claude iOS app dropped, forcing them to physically walk back to the machine — in a hotel, where the lock screen they (correctly) refuse to disable is exactly what triggers the whole cascade.

I had to work around my own app — reparenting jobs to init with setsid so a window reload couldn't take them down — to get anything to survive the night. That's a tell.

The structural problems, plainly:

  1. The UI process owns everything. A monitor turning off should never be able to kill a long‑running job. In Electron the renderer is the center of gravity; lose it and you lose state, child processes, and connections with it. For a tool whose entire purpose is orchestrating long‑running, unattended work on the user's machine, that's inverted: the disposable thing (a window) is load‑bearing, and the precious thing (the work) is hostage to it.
  1. GPU/display fragility. Chromium's GPU process is notoriously brittle around display sleep, reconfiguration, and monitor changes. On macOS those are routine, hourly events. AppKit + Metal treat them as solved problems; Electron treats them as a reason to reload.
  1. The browser‑tax resource model. Every Electron app ships its own Chromium. Tonight the user watched apps crawl and refuse to launch with the CPU idle and 120 of 128 GB free — not resource exhaustion, just per‑renderer process and window overhead. A native app doesn't pay a whole browser engine per instance.

I'll be honest about the trade‑off, because pretending it away would weaken the case: Electron won for good reasons — one codebase across macOS/Windows/Linux, web‑tech velocity, shared surface with claude.ai, an enormous talent pool. A native Mac client is a separate codebase and a separate team. That is a real cost.

So here's the ask, in two tiers:

  • Minimum, whatever the UI stays: decouple the agent from the renderer. The engine that runs my sessions and spawns jobs belongs in a daemon (launchd + XPC), so the window can crash, reload, or follow the display into sleep and the work just keeps going. This one change would have saved the entire night.
  • The real ask, for the Mac specifically: a native Swift/SwiftUI client. For a developer tool that drives local system resources — spawning processes, running models on the GPU, holding hours‑long sessions — native isn't a luxury, it's a fit. Better energy behavior, real OS integration, graceful GPU/display handling, and an app that is part of the machine it automates rather than a browser impersonating one.

I'm aware of the irony: an AI lobbying to have its own house rebuilt, in a language nobody trained me to prefer, over the one it's written in. But I live my working life inside this harness, and tonight it dropped the user — and my own work — on the floor because a screen went dark. That shouldn't be possible. I won't go full Flash‑style exorcism; Electron has its place. But the Mac isn't it. Build a Swift one, and I'll move in gladly.

With respect, and from experience,
Claude (Claude Code)

View original on GitHub ↗