Building a Menu Bar Application with Electron and React
Getting Started with Electron
Electron.js is a powerful framework that allows you to create cross-platform desktop applications using web technologies such as HTML, CSS, and JavaScript. With Electron, you can leverage Node.js APIs to create applications that run on Windows, macOS, and Linux.
Setting Up Your Project
To get started, you’ll need to set up an Electron project with React. You can use a boilerplate or create your own project from scratch. Make sure to install the necessary dependencies, including electron-util
, which allows you to conditionally enable features such as devTools in development mode.
npm install electron-util
Creating a Window with BrowserWindow API
The BrowserWindow API is used to create a browser window with specified options and load a desired URL. Create a function called createMainWindow
and use it to create a BrowserWindow instance. You’ll need to wait until the app is ready before creating the window, so use the ready
event to ensure everything is initialized properly.
const { app, BrowserWindow } = require('electron');
let mainWindow;
function createMainWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
},
});
mainWindow.loadURL('undefined.com');
mainWindow.on('closed', () => {
mainWindow = null;
});
}
app.on('ready', createMainWindow);
Creating a Tray Object
To create a tray object, you’ll need to create a class that bundles all the necessary functionalities. This class should include methods for getting the window position, showing and hiding the window, and creating a system menu when right-clicked. Use the TrayGenerator
class to create a tray object and attach the necessary event listeners.
class TrayGenerator {
constructor() {
this.tray = new Tray('icon.ico');
this.tray.setToolTip('My App');
this.tray.on('click', () => {
// Handle tray click event
});
this.tray.on('right-click', () => {
// Handle tray right-click event
});
}
getWindowPosition() {
// Get window position
}
showWindow() {
// Show window
}
hideWindow() {
// Hide window
}
}
Persisting Data with Electron-Store
Electron-store is a handy package that allows you to persist data on the main process. Use it to store user preferences or application state. Create a store with a schema and use it to toggle a value, such as “Launch at startup.”
const { Store } = require('electron-store');
const store = new Store({
schema: {
launchAtStartup: {
type: 'boolean',
default: false,
},
},
});
store.set('launchAtStartup', true);
Communication Between Renderer and Main Processes
To communicate between the renderer and main processes, use the ipcMain
and ipcRenderer
modules from Electron. These modules allow you to send and receive messages across processes using event listeners and emitters. Use IPC to send and receive data between the main and renderer processes.
// Main process
const { ipcMain } = require('electron');
ipcMain.on('message', (event, data) => {
console.log(data);
event.reply('response', 'Hello from main process!');
});
// Renderer process
const { ipcRenderer } = require('electron');
ipcRenderer.send('message', 'Hello from renderer process!');
ipcRenderer.on('response', (event, data) => {
console.log(data);
});
Customizing Menu Features
You can customize menu features by creating custom menu items using the MenuItem
object. Set the label
, click
handler, enabled
state, and accelerator
properties to create a custom menu item. For example, you can create a menu item to minimize the window or open a specific file.
const { Menu } = require('electron');
const menu = new Menu();
menu.append(
new MenuItem({
label: 'Minimize',
click: () => {
mainWindow.minimize();
},
}),
);
menu.append(
new MenuItem({
label: 'Open File',
click: () => {
// Open file logic
},
}),
);
Distributing Your Application
Once you’ve completed your application, use electron-builder to distribute it. Run npm run build
to create a production build of the React app, and then run npm run dist
to distribute your Electron app.
npm run build
npm run dist