Creating Electron Installer for Both Mac Os and Windows

So you have created up a great looking Electron-based app. Now you want to create an installer for it, There is a lot of articles that can help you, but in this, I am going to share my story of how I did it, and it is also for the people who are using electron and react together.

1️⃣First Step

var packager = require("electron-packager");
var options = {
arch: "x64",
platform: process.platform,// this will automatically select darwin if darwin or win32 if win32
dir: "./", // which directory to pack
"app-copyright": "",// fill this
"app-version": "0.0.1",
asar: true, // this will archive your source code.
icon: "./logo.ico",
name: "", // fill this
ignore: [
// list every thing that need to be ignore, so reference every single director and leave the build of the app and the files that are being used in the node module.
out: "./build/releases",
overwrite: true, // will overwrite whatever it might have written before.
prune: true,
version: "0.0.1",
"version-string": {
CompanyName: "",// fill this
"" /*This is what display windows on task manager, shortcut and process*/,
OriginalFilename: "",// fill this
ProductName: "",// fill this
InternalName: "",// fill this
packager(options, function done_callback(err, appPaths) {

2️⃣Second Step

electron-installer-windows --src pathto/packaged_app_folder/ --icon logo.ico --dest build/releases/
electron-installer-dmg ./path_to_packaged_app_folder/ name_of_the_installer --overwrite


function handleSquirrelEvent() {
if (process.argv.length === 1) {
return false;
const ChildProcess = require("child_process");
const path = require("path");
const appFolder = path.resolve(process.execPath, "..");
const rootAtomFolder = path.resolve(appFolder, "..");
const updateDotExe = path.resolve(path.join(rootAtomFolder, "Update.exe"));
const exeName = path.basename(process.execPath);
const spawn = function (command, args) {
let spawnedProcess, error;
try {
spawnedProcess = ChildProcess.spawn(command, args, { detached: true });
} catch (error) {}
return spawnedProcess;
const spawnUpdate = function (args) {
return spawn(updateDotExe, args);
const squirrelEvent = process.argv[1];
switch (squirrelEvent) {
case "--squirrel-install":
case "--squirrel-updated":
// Optionally do things such as:
// - Add your .exe to the PATH
// - Write to the registry for things like file associations and
// explorer context menus
// Install desktop and start menu shortcuts
spawnUpdate(["--createShortcut", exeName]);
setTimeout(app.quit, 1000);
return true;
case "--squirrel-uninstall":
// Undo anything you did in the --squirrel-install and
// --squirrel-updated handlers
// Remove desktop and start menu shortcuts
spawnUpdate(["--removeShortcut", exeName]);
setTimeout(app.quit, 1000);
return true;
case "--squirrel-obsolete":
// This is called on the outgoing version of your app before
// we update to the new version - it's the opposite of
// --squirrel-updated
return true;
if (handleSquirrelEvent()) {
// squirrel event handled and app will exit in 1000ms, so don't do anything else
const preloadLink = () => {
return isDev
? process.platform == "darwin"
? "file:///" + path.resolve(`./src/utils/${preload}.js`)
: "" + path.resolve(`./src/utils/${preload}.js`)
: window.location.href.split("/").slice(0, -2).join("/") +

I Describe Myself as a Polyglot ~ Tech Agnostic ~ Rockstar Software Engineer. I Specialise in Javascript-based tech stack to create fascinating applications.