Quick answer: An Electron game is Chromium fused with Node, split across a main process that owns the window and renderer processes that run your game. A crash can be a JavaScript exception in either process, a native Chromium minidump, or a native addon fault. Initialize the SDK in both processes, tag every report with the process type, and enable the Crashpad based reporter so native crashes resolve against the right symbols.
An Electron game is a Chromium browser fused with a Node.js runtime, split across a main process that owns the window and lifecycle and one or more renderer processes that run your game in a web context. A crash can be a JavaScript exception in either process, a native crash in Chromium itself, or a failure in a native Node module. Knowing which process and which layer failed is the entire triage problem, because a renderer crash may be recoverable while a main process crash always takes the whole app down. This post covers the multi process architecture, capturing JavaScript exceptions in both processes, the native crash path through Chromium minidumps, the role of native addons, and the packaging realities of shipping a desktop binary.
The multi process model
Electron runs a single main process built on Node that creates browser windows, each backed by a renderer process running Chromium. Your game logic typically lives in a renderer, while the main process handles windowing, menus, auto updates, and privileged operations. The two communicate over inter process messaging. A crash therefore belongs to a specific process, and a renderer crash does not necessarily take down the app, while a main process crash always does, which is the first thing your triage needs to know.
This split means there is no single crash handler. A renderer can throw a JavaScript exception, hit a native Chromium fault, or be killed for memory; the main process can throw in Node, crash in a native addon, or abort the whole app. Each path needs its own capture, and every report must record which process emitted it, because the same stack text means different things depending on where it ran, and a signature that blends both processes is impossible to act on.
Capturing JavaScript exceptions
In the renderer, install window.onerror and an unhandledrejection listener as you would in any web context, since your game is web code. In the main process, listen for the Node uncaught exception and unhandled rejection events to catch failures in your lifecycle and messaging code. Tag each report with the process type, main or renderer, and a window identifier, so a multi window game does not collapse distinct failures into one signature that hides which window actually broke.
Inter process messaging is a common and subtle crash source. A message handler that assumes a payload shape, or a renderer that calls into the main process after the window is gone, throws in ways that are hard to trace without context. Buffer recent messages and the current game scene as breadcrumbs in each process, so an exception carries the cross process conversation that led to it rather than a bare stack, which for a bug that spans the process boundary is often the only way to reconstruct what happened.
Native crashes and minidumps
Beyond JavaScript, Chromium itself can crash natively, taking a renderer or the whole app with it, and these do not surface as catchable exceptions. Electron exposes a crash reporter module built on Crashpad, which captures a minidump when a process crashes natively. Enable it early in the main process so native faults in Chromium or the GPU process produce a minidump you can symbolicate, since a JavaScript handler never sees these and they would otherwise vanish entirely.
Minidumps require symbols to be useful. The Electron prebuilt binaries have published symbol files for each version, and your own native Node addons need their symbols archived per build. Symbolicating a minidump against the matching Electron version symbols turns a native Chromium crash into named frames, which is the only way to tell whether the fault is in Chromium, in the GPU driver, or in a native module you bundled. A mismatched symbol set produces wrong frames, so keep symbols for every shipped version.
Native addons and the GPU process
Native Node addons are compiled C or C++ loaded into the main process, and a fault in one is a hard native crash, not a JavaScript exception. Record the set and versions of native modules you bundle, because a crash that follows an addon upgrade is almost always that addon. Pin versions and rebuild addons against the exact Electron binary interface, since a mismatch causes load time crashes that look baffling without the version context to point at the real cause.
The GPU process is its own failure domain. Chromium isolates GPU work in a separate process, and a driver bug or a problematic graphics workload can crash it, which Electron may recover from by falling back to software rendering or may propagate as a visible failure. Capture whether GPU acceleration was active and the GPU vendor and driver, so a crash clustered on one driver is recognizable as a hardware compatibility issue rather than your code, the same triage logic that applies to any driver dependent crash.
Setting it up with Bugnet
Initialize the Bugnet SDK in both the main process and every renderer, because a single integration cannot see across the process boundary. In the main process you init at app startup before creating windows; in the renderer you init in your preload or earliest script. Each instance tags its reports with the process type and the app version, and the SDK queues reports to disk so a crash during a network drop is delivered later, with an in game report button for non fatal issues in the renderer.
Bugnet folds crashes together with occurrence grouping and lets you filter by process type, the first cut you always want: main process crashes are app fatal and urgent, renderer crashes may be recoverable. You attach the messaging and scene breadcrumbs as custom fields and forward the Electron and Chromium versions, so a crash that only appears on one Electron release, often an upstream Chromium regression, is immediately distinguishable from your own logic bug and ranked by how many players it hits.
Operating across versions
Electron tracks Chromium closely and releases often, and each bump can change crash behavior, symbol files, and addon binary interface. Stamp the Electron version, the Chromium version, and your app version on every report, because a spike after an Electron upgrade frequently traces to an upstream Chromium change rather than your patch. Sort signatures by occurrence and split by process type and Electron version to attribute them correctly instead of blaming your own release.
After each release, confirm the crash reporter is still enabled and producing minidumps, that you uploaded symbols for the Electron version you shipped and for your native addons, and review the top signatures by process. Auto update means players move between versions on their own schedule, so keeping symbols for every shipped Electron version is non negotiable. A short post release check catches a disabled reporter before a wave of native crashes goes undecoded and leaves you blind to the worst failures.
Electron crash reporting is a multi process problem: init the SDK in both main and renderer, tag every report with the process type, and enable the Crashpad based reporter for native minidumps. Keep Electron version symbols and native addon symbols per build so native crashes resolve to named frames.