25

Using electron-packager I can create a 'packaged' version of my JavaScript application for various architectures and platforms. However, it does not package each build as a single binary which I can distribute.

When looking for alternatives I found out about EncloseJs, but it is not free (and I prefer a free solution).

Another one I found was electron-boilerplate, which only creates a *.deb, *.app or a Windows installer, but not a single executable which will run the program.

Is it possible to use Electron to create a single executable file?

Kees
  • 353
  • 1
  • 3
  • 5

6 Answers6

17

Try using electron-builder -p --win. it will build up the production-ready .exe. I did it with electron-builder@21.2.0

for the publishable build, you'll need the publishing provider in your package.json file, consider the given example.

"build": {
    "appId": "com.trinityinfosystem.electron.exchange.stream",
    "productName": "Accurate",
    "copyright": "Copyright © 2018 Trinity InfoSystem",
    "mac": {
      "category": "public.app-category.utilities",
      "icon": "assets/icon.icns",
      "target": [
        "zip",
        "dmg"
      ],
      "publish": [
        "github"
      ]
    },
    "win": {
      "publisherName": "Trinity InfoSystem",
      "publish": [
        "github"
      ],
      "target": [
        "nsis"
      ]
    },
    "linux": {
      "target": [
        "AppImage",
        "tar.gz"
      ]
    },
    "dmg": {
      "background": "assets/background.png",
      "icon": "assets/icon.icns",
      "title": "Accurate Installer"
    },
    "nsis": {
      "oneClick": false,
      "perMachine": false,
      "allowToChangeInstallationDirectory": true,
      "installerIcon": "assets/icon.ico",
      "installerSidebar": "assets/sidebar.bmp",
      "uninstallerSidebar": "assets/sidebar.bmp",
      "license": "assets/agreement.html",
      "createDesktopShortcut": true,
      "createStartMenuShortcut": true
    },
    "publish": [
      {
        "provider": "github",
        "owner": "vkiranmaniya",
        "repo": "accurate",
        "vPrefixedTagName": true,
        "private": true,
        "releaseType": "draft"
      }
    ]
  },

Add the given pulishing config to your package.json as root proprty. You will need the Github personal access token (here is the Doc) to be exported while running a build.

You can export the token as env variable from main.js as given,

process.env.GH_TOKEN = 'YOUR_PERSONAL_ACCESS_TOKEN_HERE';

If you want to setup AutoUpdate using GitHub, you can use the given module and call checkForUpdates() method from main.js

const electron = require("electron");
const updater = require("electron-updater");
const autoUpdater = updater.autoUpdater;

autoUpdater.on('checking-for-update', function () {
    sendStatusToWindow('Checking for update...');
});

autoUpdater.on('update-available', function (info) {
    sendStatusToWindow('Update available.');
});

autoUpdater.on('update-not-available', function (info) {
    sendStatusToWindow('Update not available.');
});

autoUpdater.on('error', function (err) {
    sendStatusToWindow('Error in auto-updater.');
});

autoUpdater.on('download-progress', function (progressObj) {
    let log_message = "Download speed: " + progressObj.bytesPerSecond;
    log_message = log_message + ' - Downloaded ' + parseInt(progressObj.percent) + '%';
    log_message = log_message + ' (' + progressObj.transferred + "/" + progressObj.total + ')';
    sendStatusToWindow(log_message);
});

autoUpdater.on('update-downloaded', function (info) {
    sendStatusToWindow('Update downloaded; will install in 1 seconds');
});

autoUpdater.on('update-downloaded', function (info) {
    setTimeout(function () {
        autoUpdater.quitAndInstall();
    }, 1000);
});

function checkForUpdates(){
    const data = {
        'provider': 'github',
        'owner':    'vkiranmaniya',
        'repo':     'exchange',
        'token':    'YOUR_PERSONAL_TOKEN_HERE'
      };
    autoUpdater.setFeedURL(data);
    autoUpdater.checkForUpdates();
}

function sendStatusToWindow(message) {
    console.log(message);
}

module.exports = {
    checkForUpdates,
}

Now you can run the command electron-build -p --win to build an auto updatable standalone .exe file. Use --mac or --linux to target specific platform for build.

Community
  • 1
  • 1
Kiran Maniya
  • 8,453
  • 9
  • 58
  • 81
12

yup, it's (now) possible. Choose any of the modules to generate single exe file: electron-builder, electron-forge or windows-installer .

GorvGoyl
  • 42,508
  • 29
  • 229
  • 225
  • 21
    These are setup/installed files. The original question was how to get a single executable (not an installer). Did I miss something? – programmer Dec 13 '18 at 01:48
  • 3
    electron-builder is creating a single executable for me (not an installer). I can choose portable option for Windows. – evayly May 24 '19 at 06:34
  • is it possible to package empty files (i.e. an empty JSON file that will eventually be used to store data), so that i dont need to check if they exist and possibly create such files at runtime??? – oldboy Jan 03 '20 at 21:51
  • is it possible to package empty files to be used in the set-up instead of having to create them??? – oldboy Feb 09 '20 at 06:03
  • @evayly which does your package.json `build` section look like to be producing a single .exe (portable, non-installer)? Specifically, what target property did you choose? – Brandon Ros Aug 05 '21 at 21:33
  • @BrandonRos I cannot really test this anymore but there is a specific portable target (windows: "win": { "target": "portable" } ) – evayly Aug 07 '21 at 17:37
10

electron single .exe:

electron-builder --win portable

It generates a single .exe !!!

And you don't need to touch package.json.

More info doc


If electron-builder show some error:

Cannot find module 'fs/promises' Electron JS

Downgrade Electron Builder using: "electron-builder": "22.10.5" or upgrade NodeJS to 14+ More info here.

Even Wonder
  • 1,127
  • 1
  • 14
  • 16
user2959760
  • 460
  • 4
  • 12
2

Not really, but that's OK.

I doubt that there are many desktop apps which consist solely of an executable. Typically you will have lots of resource files. Electron is just the same: it comes with a 'single executable' file that starts Electron and many additional files. When you use electron-packager you get a single executable that starts your app but it is bundled with lots of resource files (like your Javascript code). I suppose you could try and use some kind of bin packer to bundle everything into a single binary, but why do you want to do that? Most apps consist of many files and folders and have no issue with it.

inukshuk
  • 1,419
  • 13
  • 9
  • 2
    I was hoping this was possible with Electron 'out of the box', anyhow, thank you for your response. – Kees Apr 14 '16 at 10:01
  • 2
    Because if you don't pack everything inside a single executable file, the clients can see the source code. The resources folder is exposed to the client when you just use electron-packager – Bijay Timilsina Aug 30 '17 at 11:31
  • so is it possible to package empty files (i.e. an empty JSON file that i use to store data), so that i dont need to create these files at runtime and always check if they exist at runtime? – oldboy Jan 03 '20 at 21:50
  • Bijay - if you pack the source into an asar (typical for Electron) then your code is somewhat shielded, furthermore the asar can be put into a mostly out of view location (like AppData in Windows). If you're really trying to protect your source then stuffing the original code into the exe won't save it. Obfuscate the code or use more advanced tools/techniques. – DAG Sep 13 '20 at 13:12
  • It does not look so good to (layman) users when there are lots of files come along with the exe file. – Avin Shum Jan 04 '21 at 06:36
2

I'm not sure if there is a newer solution but you can use BoxedApp, You had to buy it though but you can search for a free version.

You can also use WinRAR, your project will pack into single exe by creating SFX archive. Here is a video on How To Make Portable Application using WinRAR.

CONS: launching application will takes longer.

NOTE: You have to pack your project first before using any of the method above.

PS: Tested on Windows only.

Hope this help.

Polar
  • 3,327
  • 4
  • 42
  • 77
1

For those using electron-forge, we've built a Maker plugin that builds a portable Windows .exe file using electron-builder's portable target under the hood:

https://github.com/rabbit-hole-syndrome/electron-forge-maker-portable

gregnr
  • 1,222
  • 8
  • 11