Publishing for Windows

This article is part of the Distributing Electron apps series.

If you're looking to publish for OS X, check out previous post.

What's the endgame?

To build EXE installer for our app and be able to automatically update.

Creating installer

If you followed through article where I explained electron-builder, you're mostly done to build distributable for Windows.

Let's clear some things first. It's not the same if you run electron-builder from Windows or OS X.

If you build it from Windows, you can create delta packages and MSI installer. Delta packages are binary diffs of your 2 versions.

So electron-builder can generate this:

  • Application setup (.exe)
  • Squirrel update package (.nupkg)
  • File with list of releases (RELEASES)
  • Delta package (.nupkg) - only on Windows
  • MSI installer (.msi) - only on Windows

You can customize build with this options.

I'm using OS X machine to build for both platforms, so I'll be concentrating on it, but let me just mention couple of things.

Running electron-builder on Windows will generate MSI installer, but not delta packages. By default, electron-builder will put all of the files in dist directory. Each time that you start build, it will remove all files from folder and generate new ones. That is the problem since delta updates are created based on RELEASES file which contains list of files. It will take last one and create delta package between last file and current one. To avoid this, you need to define outputDirectory in your package.json. That way, generated files are not removed and RELEASES file is updated for each version.

Note: Although this created delta packages for me, build process failed since electron-builder was expecting certain file in certain folder which wasn't respected. Just a heads up.

Electron-builder will use Squirrel.Windows to create nupkg files which are relevant for auto-updater.

Automatic updates

Auto-updating your application on Windows doesn't require any server, but only path to the folder where your RELEASES file and .nupkg files are stored.

First, we need to handle Squirrel events on application startup. There is neat little module that you can use which will handle this for you. Do this on the very beginning of your app, and then proceed with including auto-updater:

if(require('electron-squirrel-startup')) return;

const autoUpdater = require('auto-updater');  

Then if you'd like, you can add listeners for relevant events:

autoUpdater.addListener("update-available", function(event) {  
autoUpdater.addListener("update-downloaded", function(event, releaseNotes, releaseName, releaseDate, updateURL) {  
autoUpdater.addListener("error", function(error) {  
autoUpdater.addListener("checking-for-update", function(event) {  
autoUpdater.addListener("update-not-available", function(event) {  

Next, we need to provide auto-updater with URL to where assets are stored. I'm separating resources by their architecture, so I'm provide following URL:

const os = require('os');  
const feedURL = '' + (os.arch() === 'x64' ? '64' : '32');  

Now everything is setup, so finally you need to request checking for update:


In the end...

Upload all generated files to appropriate server folder. Keep in mind that you'll have to have one RELEASES file with list of .nupkg files which needs to be stored in same folder. Electron-builder does all of this for you so just upload all generated files from dist folder.

You can sign your application on OS X by exporting your key to p12 format. Then just follow instructions provided here (simply change pem for p12). Also, electron-windows-installer has options certificateFile and certificatePassword (didn't test it out though).

Thoughts? Improvements? Problems? Feel free to drop a comment.

About Vjekoslav Ratkajec

Software developer from Zagreb, Croatia. Love programming, running, hiking and biking. Adore nature and animals. Also author of this blog.