Accepted answer

I recently researched methods of integrating Election + React & I highly recommend using electron-forge & adding React like this:

That article gives you good context from an experienced Slack engineer, but essentially reccommends you follow this in the electron-forge docs:

That is the simplest integration possible & you'll be on solid footing with electron-forge, instead of a GitHub boilerplate.

I however started with a create-react-app project. When combining 2 frameworks, each with large package.json & lots of build tooling I do not like to merge their package.json in a single project. Instead I nested a CRA project inside of electron-forge, & I tell electron to load the /build folder out of CRA. This works for packaging the app, but during development I use electron-is-dev to load the CRA dev server on port 3001 instead. Use a .env config to change the port the CRA dev server uses to 3001, because both electron-forge & CRA want to use 3000 by default.

To connect actions from your tray window with the main app window, use IPC messages to communicate between those 2 Renderers, with the Main process in between to relay the messages.


You can use Tray in electron for this

Quote from the tray docuentation

Add icons and context menus to the system's notification area.

Example code:

const { app, Menu, Tray } = require('electron')

let tray = null
app.whenReady().then(() => {
  tray = new Tray('/path/to/my/icon')
  const contextMenu = Menu.buildFromTemplate([
    { label: 'Item1', type: 'radio' },
    { label: 'Item2', type: 'radio' },
    { label: 'Item3', type: 'radio', checked: true },
    { label: 'Item4', type: 'radio' }
  tray.setToolTip('This is my application.')


Your best solution given the existing parameters, would probably be to have a separate route in your application (since you don't want a separate html page), and when the tray icon is clicked, wire it to something like

const window = new BrowserWindow();

Related Query

More Query from same tag