Electron developers face a unique problem: errors happen in two completely separate processes simultaneously. Your main process (Node.js) might crash while trying to access the file system, while your renderer process (Chromium) throws an exception in the UI, and neither talks to the other by default. Without unified Electron app error tracking monitoring, you're flying blind — main process crashes vanish into stderr, renderer errors hide in the DevTools console, and you won't know anything broke until a user files a support ticket two days later. The solution is to instrument both processes and funnel errors to a single dashboard, so you catch production failures in real time and fix them before they spread.
This guide walks through setting up production-grade error tracking in an Electron app using the Sentry SDK pointed at LightTrace. By the end, errors from both the main process and renderer will be captured, grouped, and ready to fix.
Why Electron error tracking is different
Electron is two processes in one application. The main process is pure Node.js — it handles file I/O, spawning child processes, system tray interactions, and window lifecycle. The renderer process is Chromium — it renders the UI, runs your React or Vue components, and handles user interactions. They communicate via IPC (inter-process communication), but they crash independently.
A rendering error in the UI doesn't crash the main process. A file system permission error in main doesn't affect the renderer. This is Electron's strength for stability — one process crashing doesn't bring down the whole app. But it's also a debugging nightmare: without unified error tracking, you have to stitch together logs from two separate runtimes to understand what actually failed.
The pattern is straightforward: initialize the error-tracking SDK twice — once in the main process and once in the renderer — and configure them to report to the same project. Both processes send errors to the same dashboard, where they're grouped and contextual, so you see the full picture.
Electron ships with a default crash reporter in the main process, but it's limited — it only captures crashes, not exceptions, and doesn't provide a dashboard or grouping. A proper error tracker gives you full visibility into both processes and automatic alerts when something breaks.
Install the SDKs
The Sentry SDK for Electron is built on top of the Node.js and React/browser SDKs. Install it alongside your existing Electron dependencies:
npm install @sentry/electron @sentry/node @sentry/react
If you're not using React in your renderer, you can skip @sentry/react and use the browser SDK instead (@sentry/browser), but since most Electron apps do use a framework, @sentry/react is the most common choice.
Initialize the main process
The main process runs first, so initialize the Sentry SDK as early as possible in your main file:
// main.js (or main/index.js)
import * as Sentry from "@sentry/electron/main";
Sentry.init({
dsn: "https://<key>@light-trace.robomiri.com/1",
environment: process.env.NODE_ENV,
release: "myapp@1.2.3",
tracesSampleRate: 1.0,
});
import { app, BrowserWindow } from "electron";
app.on("ready", () => {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, "preload.js"),
},
});
mainWindow.loadFile("index.html");
});
That single init call installs global handlers for uncaught exceptions and unhandled promise rejections in the main process. Any error thrown in your main-process code — from require() errors during startup to runtime failures in IPC handlers — is now captured and queued for upload to LightTrace.
Send errors from the main process to the renderer
The renderer needs to know about main process errors so it can log them to LightTrace (since the renderer has network connectivity and the main process may not in some security configurations). Use IPC to forward errors:
// main.js - send errors to renderer
import { ipcMain } from "electron";
ipcMain.handle("log-error", (event, error) => {
Sentry.captureException(error);
console.error("Main process logged error:", error);
});
The renderer will call this handler when it needs to report a main process error (or for any critical logging). This ensures both processes report to the same Sentry project.
Initialize the renderer process
The renderer process is where your UI code runs. Initialize Sentry here as well, before your app mounts:
// renderer/main.tsx (or src/index.tsx)
import * as Sentry from "@sentry/react";
import React from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
Sentry.init({
dsn: "https://<key>@light-trace.robomiri.com/1",
environment: process.env.NODE_ENV,
release: `myapp@1.2.3`,
tracesSampleRate: 1.0,
});
const root = createRoot(document.getElementById("root")!);
root.render(
<Sentry.ErrorBoundary fallback={<ErrorFallback />}>
<App />
</Sentry.ErrorBoundary>
);
The dsn is the same as the main process — both are reporting to the same LightTrace project. The Sentry team routes them correctly based on the environment and other tags.
Wrap components with error boundaries
React components in the renderer can throw errors during render or in lifecycle methods. Catch these with error boundaries so they don't crash the renderer:
// App.tsx
import * as Sentry from "@sentry/react";
export function App() {
return (
<Sentry.ErrorBoundary fallback={<ErrorFallback />} showDialog>
<MainLayout />
</Sentry.ErrorBoundary>
);
}
function ErrorFallback() {
return (
<div style={{ padding: "2rem", fontFamily: "sans-serif" }}>
<h1>Something went wrong</h1>
<p>The application encountered an error. Please restart.</p>
</div>
);
}
The showDialog option displays a native dialog to the user when an error boundary catches something, so they know the app is having trouble instead of it silently failing.
Add tags and context to both processes
Context makes errors fast to fix. Tag every event with the release and environment, and add user info so you know who was affected:
// main.js
Sentry.setTag("process", "main");
Sentry.setContext("app", {
version: app.getVersion(),
userDataPath: app.getPath("userData"),
});
// renderer/main.tsx
Sentry.setTag("process", "renderer");
Sentry.setUser({ id: userId });
Sentry.addBreadcrumb({
category: "ui",
message: "App initialized",
level: "info",
});
The "process" tag lets you filter issues by whether they came from the main or renderer process, which is critical for Electron apps. The release tag pins each error to the exact deploy that introduced it, so you can roll back with confidence if needed.
Set the "process" tag early and consistently. When debugging an issue that affects both processes, you'll want to quickly see whether it's a main-process failure (system-level) or a renderer failure (UI-level).
Unified stack traces with source maps
In production, both your main and renderer code are bundled and minified. A raw stack trace from the renderer looks like app-4f9a.js:1:52210 — useless. The main process stack trace points at bundles instead of your source files. Upload source maps to make them readable.
For the renderer (likely built with Vite, Webpack, or esbuild):
// vite.config.ts
export default defineConfig({
build: {
sourcemap: true,
},
});
For the main process, if you're bundling it (which is optional but recommended):
// esbuild.config.js
require("esbuild").buildSync({
entryPoints: ["main/index.ts"],
bundle: true,
outfile: "dist/main.js",
sourcemap: true,
external: ["electron"],
});
Then upload both to LightTrace during CI/CD:
npm run build
sentry-cli releases files upload-sourcemaps dist/ --release myapp@1.2.3
Never upload source maps to your app bundle or ship them to users. Upload them only to LightTrace, where they're used server-side to decode stack frames. Source maps contain your original source code, so treat them as sensitive.
Test your setup
Before shipping to production, verify that both processes report errors correctly. Add a test button to your renderer:
export function TestErrorButton() {
const handleRendererError = () => {
throw new Error("Test renderer error");
};
const handleMainProcessError = async () => {
const result = await window.electron.ipcRenderer.invoke("log-error", {
message: "Test main process error",
stack: new Error().stack,
});
};
return (
<div>
<button onClick={handleRendererError}>Test Renderer Error</button>
<button onClick={handleMainProcessError}>Test Main Process Error</button>
</div>
);
}
Deploy to a staging build, trigger both errors, and check your LightTrace dashboard. You should see two separate issues (or one issue with two stack traces), both tagged with your release and process type. Once you see them arrive with full context, you're ready for production.
Key differences from add-error-tracking-to-your-app
Electron app error tracking differs from standard web or server error tracking in three ways:
-
Dual-process initialization. You must set up the SDK twice — once in main, once in renderer — both pointing to the same LightTrace project. They're separate runtimes, so they need separate handlers, but they feed the same dashboard.
-
IPC forwarding. The main process often lacks network connectivity (some Electron apps run offline). Use IPC to forward main-process errors to the renderer for upload, or configure the renderer to periodically pull and upload logs from the main process.
-
Source maps for two runtimes. You're bundling and minifying two separate codebases (main and renderer). Upload source maps for both, or you'll see unreadable stack traces. The sentry-cli command handles both at once if you point it at a directory with both builds.
For a broader setup guide that covers all languages and frameworks, see how to add error tracking to your app. For debugging production errors once they arrive, see how to debug production errors.
The path to Electron stability
Once error tracking is in place, crashes stop being user complaints and become one-click bug reports. You'll see which errors affect the most users, which deploy introduced a regression, and exactly what the user was doing when it broke. The breadcrumb trail from both processes gives you reproducible scenarios, and release health tracking tells you when a new deploy is stable enough to ship widely.
Start tracking errors in minutes
Point the Sentry SDK at LightTrace and capture Electron errors — both main process and renderer — from day one. Your first 5,000 events every month are free.
Electron brings desktop power to web developers, but without production error tracking, that power comes with a blind spot. This setup closes it.