TL;DR: Electron is awesome but Electron updating needs to be configured to work well. If an update is in progress, with a few simple steps, you can configure a warning that tells the user not to shut down an application when it’s updating—proactively eliminating problems and saving time.

Are you having difficulty with Electron installing an update and the application not loading? This occurred during one of my recent engagements where we were using Electron 4.0.0 and Electron Forge ^5.2.4. We had an application set to automatically download updates from our GitHub release repo. However, if the application was closed before the update was complete, the next time the application loaded it tried to load the new, incomplete version.

I considered removing automatic updating, but that doesn’t actually address the root of the issue. The problem remains with a manual update. There are two ways to fix the issue once it happens: You can either uninstall and install the new version of the application or you can go into %USERPROFILE%\AppData\Local\smartconnector and delete the newest, partially installed version. The application will then start up as the old version and attempt the update again.

Neither of these is a very elegant solution, especially since they require end-user troubleshooting. In an effort to minimize bad user experience and decrease support time, we wanted to try and pre-empt the issue. Here’s the solution we came up with:

First, inside our base index.js, we import the autoUpdater.

import { app, autoUpdater, ipcMain } from 'electron';==

Then we subscribe to autoUpdater events to create a global variable that tracks when we are updating.

autoUpdater.on('update-available', () => {
  global.updating = true;
  global.mainWindow.webContents.send(
    'updateUpdateNotification',
    'update-available'
  );
});

autoUpdater.on('update-downloaded', () => {
  global.updating = false;
  global.mainWindow.webContents.send(
    'updateUpdateNotification',
    'update-downloaded'
  );
});

This allows us to check if the application is updating anywhere within the project and also creates an event for when it starts updating and when updating finishes.

Second, we created a warning component to notify the users about the update in progress.

import React from 'react';
import log from 'electron-log';
import { ipcRenderer } from 'electron';

export default class UpdateNotifier extends React.Component {
  constructor(props) {
    super(props);

    this.updateNotifierState = this.updateNotifierState.bind(this);

    this.state = {
      showUpdater: false,
      message: 'Installing update. Please do not close SMART Connector.'
    };
  }

  componentDidMount() {
    ipcRenderer.on(
      'updateUpdateNotification',
      this.updateNotifierState
    );
  }

  componentWillUnmount() {
    ipcRenderer.off(
      'updateUpdateNotification',
      this.updateNotifierState
    );
  }

  updateNotifierState(e, data) {
    if (data === 'update-available') {
      this.setState({
        showUpdater: true
      });
    } else if (data === 'update-downloaded') {
      this.setState({
        showUpdater: false
      });
    }
  }

  render() {
    return (
      <div>
        {this.state.showUpdater && (
          <div className="update-notifier progress">
            <div
              className="progress-bar progress-bar-striped progress-bar-animated"
              role="progressbar"
              aria-valuenow="75"
              aria-valuemin="0"
              aria-valuemax="100"
            >
              {this.state.message}
            </div>
          </div>
        )}
      </div>
    );
  }
}

Third, we devised a function to warn the user when they try to close the application. The message would indicate that closing the application without finishing the update will cause errors the next time they try to open the application. Before I was able to complete this work, I rolled off the project. However, during my research, I found there is an event-close event to hook into. Its documentation can be found here on the Electron website.

This demonstrates how, with a little proactive problem-solving, we can clear some of the roadblocks to working with Electron. Even with the small update issues, I find configuring Electron upgrades more pleasant than the more extensive setup required for a similar program in Winforms or WPF. The ease of development and upgrading were two of the main reasons I chose Electron for this project—and I would do it again if I were in the same situation. It’s a great solution for small applications. I hope this fix makes life a little easier for those of you who feel the same!

Let's Talk

Have a tech-oriented question? We'd love to talk.