Skip to main content
@reticlehq/electron reaches the two places the renderer-side SDK cannot: the IPC boundary, and capturePage(). Install it if your app is Electron and you want main-process IPC observable or the window screenshottable. A web app never needs it. Apache 2.0. Depends on @reticlehq/core. Peer dependency: electron >= 22. No build step.

Why it exists

In Electron the interesting failures happen across IPC. The renderer asks the main process for something, the main process quietly fails, and the renderer-side SDK sees nothing at all. That reads as “this app makes no backend calls” rather than “you are blind to them”.

Exports map

There is no . export. Two subpaths only.

The preload

It must run before require('electron') and before any contextBridge.exposeInMainWorld call. It patches ipcRenderer while those methods are still writable, so ordering is not a style preference.
It patches three methods, and each IPC call then surfaces to Reticle as a network record on ipc://<channel> with initiator: 'ipc': It then exposes window.__reticleIpc through the context bridge, with four members used by the SDK rather than by you:

The main process

installReticleCapture(win, options?): void is a no-op on null or undefined, tracks the window until it closes, and registers the capture handler once for the whole app. { label: 'settings' } names the window in reticle_session { action: "list" }; without it the window is listed by url and title. The handler calls webContents.capturePage(), writes the PNG into a per-process 0700 captures directory as reticle-capture-<n>.png, and returns the file path rather than the bytes, because the transport has a 64KB cap. It refuses fullPage: true explicitly rather than silently returning a viewport shot, and it throws named reasons rather than one blanket silence: full-page-unsupported for that refusal, window-not-composited when the window had nothing painted yet, no usable webContents to capture when the window is gone. The preload re-throws the full-page refusal and turns everything else into null.

Renderer wiring

The renderer still needs the SDK. Connect only in development, never in the app you ship. For example, send !app.isPackaged from the main process to the renderer, and connect only when it is true. An Electron renderer reports NODE_ENV=production, so the call also needs allowInProduction:
The bridge refuses a connect without the pairing token, also from a file:// page. For an Electron app without the Vite plugin, reticle init does not write reticle.local.js. Make it from ~/.reticle/pairing-token as the browser page shows, and add it to .gitignore. Keep reticle.local.js out of the package: electron-builder files: ["!reticle.local.js"], or Electron Forge packagerConfig.ignore: [/reticle\.local\.js$/]. With the Vite plugin, use reticle({ desktop: true }) instead. The plugin passes the token and allowInProduction, and a production-mode build ships no Reticle code.

Desktop setup in full

Electron and Tauri wiring, and what reticle doctor checks for each.
Last modified on October 25, 2026