This article is based on Window Auto Update example repository. Feel free to clone and try it here.
It's not that important to know how this works behind the scenes, so let's just quickly go through some terms:
electron-builder uses Squirrel, a packager capable of building setup files for .exe binaries automatically.
You need an installer because just a bold .exe file itself cannot be auto updated with Electron. That's why you need a packager capable of calling Squirrel.
Since Squirrel is a Windows application, you still need some runtime. On Linux or Mac you can simply use Wine.
I would recommend this perfect tutorial how to install Wine on the Mac via brew: https://www.davidbaumgold.com/tutorials/wine-mac/.
The update process itself is based on .nupkg packages (=binary format similar to .zip) which holds source code of your application.
Squirrel generates your-app-1.0.0-full.nupkg which is a complete application binary and if it's possible it also generates a file called your-app-1.0.0-delta.nupkg.
This *-delta.nupkg file is important for auto updates. This file holds a patch that needs to be applied to previous version of your app to update to the next version.
So how can you force electron-builder to create such file for you?
The key is the RELEASES file. This file is always generated by Squirrel. It is simply a list of available app versions with checksums and names of *.nupkg files for every version.
Alright, first make sure you are on a Windows machine. If not, just download and install Wine - Mac guide here.
Once you are done with that, you can install this repo:
Alright, verify that everything works by starting a prebuild of our app:
What an app, right? Note that version number is dynamic and will change when we update our app.
Let's try to create the Windows build I have prepared for you:
Well, this fails. The reason it fails is that I have added a line that tells Squirrel where it should find all my app releases in RELEASES file.
Now let's just delete one line from package.json, so we can build the windows app. Note that electron-builder uses package.json to configure the build, and so far I got everything I needed without any programming required.
Now everything should go OK. If you have troubles with Wine make sure you did all of the steps described above.
NOTE that in package.json this part:
I generated dummy certificates to sign this app. If you won't provide these files, autoUpdate will not work, so you better replace these lines with your own certificate info.
FYI: Guide to generate such certificates is here: https://www.npmjs.com/package/electron-installer-windows
So what do we have now? Well, in dist/win there is something like electron-windows-autoupdate-1.0.0-full.nupkg which is packed binary. Along with electron-windows-autoupdate Setup 1.0.0 which is Windows installer of our App. Great.
If you don't like the file name, just change name key in package.json.
The most important part to make Windows AutoUpdate work is however this simple text file RELEASES (dist/win/RELEASES).
This file is the key to create *-delta.nupkg files needed for auto update. Squirrel must be able to find this file, however electron-builder only supports web links to the release file in config. But is that an obstacle for a programmer like you? Of course not.
It's time to make folder dist/win accessible over the internet. In production, you would probably upload all these artifacts from dist/win to S3 bucket or whatever, and just pasted the links. Well, in dev mode, we would be OK just with SimpleHTTPServer which is shipped on Mac as well as on Linux and Windows if you download python. You can of course use any other server, that can server static files, express, webpack, apache, nginx whatever. The only requirement is that we have a web url that points to dist/win.
Firstly rename dist/win to some other name (I use dist/win1). The reason for renaming is that the electron-builder would overwrite folder dist/win with all it's content, In order to keep it unchanged for the auto update, just rename it.
Now if you do:
it should open RELEASES in the browser, maybe it downloads it - everything but the 404 error is OK.
Next we have to tell Squirrel that we already have some versions of our app built and we want another version to be and update of older ones.
To do that, just bump version in package.json to eg. 2.0.0. If you won't bump version, new build will not be an update of previous version.
Now let's put back that line we deleted from electron-builder config in package.json.
So your key build in package.json should look like this.
NOTE that in remoteReleases you only need to specify the path to the folder where RELEASES and *-*.nupkg files are, not the path to individial files!
So run again the build script:
dist/win and dist/win1 should be in the dist folder.
To verify that Squirrel has seen previous RELEASES, take a look into dist/win/RELEASES. And here you should see something like this:
If there is just one line, it means that you did not bump version in package.json.
If you have 3 lines, well done. Squirrel noticed a previous version and created *-delta.nupkg which holds the difference between the older version and current one. There is also a note about *-full.nupkg which is a package binary of the next version of your app that you just built.
Now that all the update files are prepared we may implement app code that will implement auto update in the app.
All the magic you can see in index.html.
Things to notice are:
Note this line autoUpdater.setFeedURL('http://localhost:9000/dist/win/'). AutoUpdater uses Squirrel in the background, so it requires a URL to a folder where all the required files are located. These files are familiar *-full/delta.nupkg and RELEASES.
But this time, this url must point to a folder where update files are located.
In our case, we have old update files in dist/win1 but files for a newer version (along with RELEASES with all the versions) is in dist/win.
Next we will try install and auto update our app, we have to start a server that would point to dist/win and set autoUpdater.setFeedURL() accordingly, so we have to run this on the Windows machine.
We can copy update files to windows machine, or upload them to the web, and set the url, so that it points to the folder with *.nupkg and RELEASES.
You can use SimpleHTTPServer again even on Windows, just make sure you have python installed and in your PATH.
You can clone this repo and run:
Again and it should all work.
Now, this is the time to run windows installer, but make sure you install the first version from dist/win1/*Setup<version>.exe!!
Once done, you should see Current version is: 1.0.0 in our awesome app. Also you should see some logs in console saying that an update is available, then that the update is available, being downloaded and finally an alert pop ups, confirm it and App will automatically update.
Now you see Current version is: <BUMPED VERSION>
No update is available
Make sure that dist/win is accessible via browser on your Windows machine. Make sure you have correct url set on updater by calling autoUpdater.setFeedURL().
/RELEASES/ not found
Make sure server is running and "remoteReleases" in package.json is set correctly.
Cannot get signature of running application
Code sign was not applied, take a look here how to generate one: https://www.npmjs.com/package/electron-installer-windows
Let me know how it works for you, either in the comments below or on Github where you can also find a run example.