Share application data in Electron Apps using the global object

Jeremy Lu
3 min readAug 12, 2020

--

Ring Lamp Illuminates Hand
Photo by Nadine Shaabana | Unsplash

One of the main challenge of Electron development is sharing data within the application between the ‘main’ and the ‘renderer’ processes. The first idea that would come into our mind is to setup IPC events to keep the data in sync. Or combine with the global state management frameworks such as Redux or MobX. While these methods or tool will have their time and places. It’s costly to add and setup the libraries and boilerplates.

For example, I want to add a file menu to allow the user to choose different language preferences. The user can select which language to use in the application by clicking on the file menu:

The file menu logic is handled via the main process. After the update, the renderer UI can render different languages base on this global value. For simple use cases such as this, the IPC events or framework options can overkill.

One leaner option of choice is to use the ‘global’ variable that is shared among main and renderer processes. Take my original language preferences use case. Here are the steps to set this up:

  1. Create a ‘global.js’ file with following content:
global.shared = {
targetLanguage: 'eng'
};
export default global;

2. Add your import or require ‘global.js’ in the main process’s entry file (‘index.js’), after all library dependencies and before any application dependencies such as your menu ‘template.js’:

import { app, Tray, BrowserWindow, Menu, dialog } from ‘electron’;
import * as path from ‘path’;
import global from ‘../common/global’;
import menuTemplate from ‘./file-menu’;

3. Now you are able access global.shared from main. It’s not necessary to import it. And use it as:

global.shared.targetLanguage = ‘eng’;

4. You can access (read/write) global.shared from renderer process via ‘remote.getGlobal()’ method.

let { targetLanguage } = remote.getGlobal(‘shared’);

This is it. This is how to setup global variables that is shared across main and renderer process.

In conclusion, while this is a very simple technique to share global data. The drawback is obvious: it may pollute the global application namespaces. There are already countless of articles written on why should avoid using global (or the Window) variables/objects. The main reason is that if we make the global variables available too easy to read and write, then the global scope will be hard to maintain as application grows. You don’t know when and where the global variables are updated or even deleted. So, back my original point, for simple use cases this solution works great. It won’t fit your application any more when it grew into a certain size. That’s probably a good time for a global state manager. However, there are still serval options helps to delay the need to have a global state manager:

  1. By adding sub-namespaces, eg. ‘global.shared.user.preferences.targetLanguage’
  2. Use ‘Object.freeze()’ and/or ‘Object.seal()’ methods to safeguard the shared object.
  3. Use immutable objects for where they are applicable.

Thank for reading, and happy coding.

--

--

Jeremy Lu
Jeremy Lu

No responses yet