Build Angular Desktop Apps With Electron

Based on Jeff Delaney post. You can also check the video lesson on youtube and the original source code on github.

You can also find my source code on github.

Generate the angular app

You can follow the Angular – QuickStart or just do these steps:

npm install -g @angular/cli
ng new angular-electron
cd angular-electron

Update base tag on index.html

The generated root page in Angular points the base href to / – this will cause problems with Electron later on, so let’s update it now.

<base href="./">

Install Electron

npm install electron --save-dev

Configure Electron

Create a new file named main.js in the root of your project – this is the Electron NodeJS backend. This is the entry point for Electron and defines how our desktop app will react to various events performed via the desktop operating system.

const { app, BrowserWindow } = require('electron')

let win;

function createWindow () {
  // Create the browser window.
  win = new BrowserWindow({
    width: 600, 
    height: 600,
    backgroundColor: '#ffffff',
    icon: `file://${__dirname}/dist/assets/logo.png`


  //// uncomment below to open the DevTools.
  // win.webContents.openDevTools()

  // Event when the window is closed.
  win.on('closed', function () {
    win = null

// Create window on electron intialization
app.on('ready', createWindow)

// Quit when all windows are closed.
app.on('window-all-closed', function () {

  // On macOS specific close process
  if (process.platform !== 'darwin') {

app.on('activate', function () {
  // macOS specific close process
  if (win === null) {

The createWindow function defines the properties of the program window that the user will see.

Notice we are loading the window by pointing it to the index.html file in the dist/ folder. Do NOT confuse this with the index file in the src/ folder. At this point, this file does not exist, but it will be created automatically in the next step by running ng build –prod

Custom Build Command

The deployed desktop app will be an Angular AOT build – this happens by default when you run ng build –prod. It’s useful to have a command that will run an AOT production build and start Electron at the same time. This can be easily configured in the package.json file.

  "name": "angular-electron",
  "version": "0.0.0",
  "license": "MIT",
  "main": "main.js", // <-- add this
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "electron": "electron .", // <-- add this to run electron 
    "electron-build": "ng build --prod && electron ." // <-- add this to build app in prod with AOT and then run electron 
  // ...omitted

Run the electron app

You can run your angular app as an native desktop app with the following command.

npm run electron-build

At this point, you can run the command (it will take a few seconds) and it will create the dist/ folder and will automatically bring up a window on your operating system with default Angular app.

This setup does not support hot code reloads. Whenever you change some Angular code, you need to rerun the electron-build command. It is possible to setup hot reloads by pointing the window to a remote URL (such as https://localhost:4200) and running npm start in a separate terminal and then running npm run electron.

Build you Angular App

This section is up to you, if you want something ready, check the Jeff’s post.

Packaging for Desktop Operating Systems

This section is slightly different from the original post, because I had to add –no-prune and a series of –ignore to let electron-packager works as expected.

The electron packager tool will allow to package our code into an executable for desktop platforms – including Windows (win32), MacOS (darwin), and Linux. Keep in mind, there are several other electron packaging tools that might better fit your needs.

npm install electron-packager -g
npm install electron-packager --save-dev

Build an executable for Windows:

electron-packager . --platform=win32 --no-prune --ignore=/node_modules --ignore=/e2e --ignore=/src

Build an executable for MaxOS:

electron-packager . --platform=darwin --no-prune --ignore=/node_modules --ignore=/e2e --ignore=/src

The you can add an npm script electron-package-win to easy package for Windows:

 "name": "angular-electron",
 "version": "0.0.0",
 "license": "MIT",
 "main": "main.js",
 "scripts": {
 "ng": "ng",
 "start": "ng serve",
 "build": "ng build --prod",
 "test": "ng test",
 "lint": "ng lint",
 "e2e": "ng e2e",
 "electron": "electron .",
 "electron-build": "ng build --prod && electron .",
 "electron-package-win": "ng build --prod && electron-packager . --no-prune --ignore=/node_modules --ignore=/e2e --ignore=/src --overwrite" // <-- add this script
 // ...omitted

Then call it like this:

npm run electron-package-win

Change default language on Bash on Ubuntu on Windows

I always forgot how to change the language on ubuntu, my windows knows that I’m Italian even if my operating system is set to be in English, and installs the bash on ubuntu on windows in Italian 😦 so I always need to do these steps:

  1. Install the language pack you want

    sudo apt-get install language-pack-en language-pack-en-base manpages

  2. Change the default language

    sudo update-locale LANG=en_US.UTF8

Installing Microsoft® Windows PowerShell Extensions for Microsoft SQL Server 2016 (AKA sqlps)

The PowerShell modules (aka sqlps) are installed by default when installing Microsoft SQL Server.

You can manually install the PowerShell Extensions for SQL Server 2016 by installing the following components from the Microsoft® SQL Server® 2016 Feature Pack:

  1. Microsoft® System CLR Types for Microsoft SQL Server® 2016 (SQLSysClrTypes.msi)
  2. Microsoft® SQL Server® 2016 Shared Management Objects (SharedManagementObjects.msi)
  3. Microsoft® Windows PowerShell Extensions for Microsoft SQL Server® 2016 (PowerShellTools.msi)


Check if the module has been successfully installed:

# Import the SQL Server Module.
Import-Module Sqlps -DisableNameChecking

# To check whether the module is installed.
Get-Module -ListAvailable -Name Sqlps

Check-out the official complete guide SQL Server PowerShell.

Getting Started with Azure PowerShell (Classic)

Thanks to opsgility (original post).

For the new AzureRM (resource manager model) please check the official: Get started with Azure PowerShell cmdlets.

Download the Azure PowerShell Cmdlets

Windows install that you can also found at Microsoft Azure Downloads

Configure your Azure Subscription with the Azure PowerShell Cmdlets.

The simplest way to access your Azure subscription from PowerShell is to use the Add-AzureAccount cmdlet.


After executing the cmdlet a dialog will appear to prompt you to login with your Microsoft or Organization account. After you login, you will have access for 12 hours before you have to login again.

Enumerating and selecting a subscription

You can use the PowerShell cmdlets to enumerate and view your current subscription settings.
Here are some of the more handy ones to know about:

# Enumerates all configured subscriptions on your local machine.

# Returns details only on the specified subscription
Get-AzureSubscription -SubscriptionName "mysubscription"

# Select the subscription to use
Select-AzureSubscription -SubscriptionName "mysubscription"

# Sets the mysub subscription to be the default if one is not selected.
Set-AzureSubscription -DefaultSubscription "mysub"


When using the WA Cmdlets with Virtual Machines (IaaS) or Cloud Services (PaaS) you will need to specify the CurrentStorageAccount for your subscription. This is basically the storage account that will be used for creating VHDs or uploading .cspkg files. For virtual machines this storage account has to be in the same datacenter that you plan on creating virtual machines in.

Set-AzureSubscription -SubscriptionName "mysub" -CurrentStorageAccount "mystorageaccount"

To discover if you have a storage account or create a new storage account from PowerShell:

# Discover whether you have a storage account already

# Creates a new storage account in the West Europe data center
New-AzureStorageAcount -StorageAccountName "mystorageaccountname" -Location "West Europe"

Which of course begs the question – how do I know which data centers are available?

The following cmdlet will give you that information:


This is everything you need to configure the Azure PowerShell cmdlets for your subscription!

Performance best practices for SQL Server in Azure Virtual Machines (link to resources)

How to create striped disk on azure (AKA Raid 0)

Disk Striping use multiple disks and stripe them together to get a combined higher IOPS and Throughput limit. Note that the combined limit per VM should be higher than the combined limits of attached premium disks.

You can check the maximum number of disks you can add to a virtual machine from here: Sizes for Windows virtual machines in Azure

1. Create “new disk” from powershell:


# RM stands for resource manager, and is the new way of managing things in Azure

# you need to login the first time using this command
# Login-AzureRmAccount

$vm = Get-AzureRmVM -ResourceGroupName "md-test-stripe" -Name "md-test-stripe"

# adds 16 disks
for($i=1; $i -le 16; $i++) {
    $name = "md-test-stripe-disk{0:00}" -f $i
    $lun = $i - 1
    $vhdUri = "{0:00}.vhd" -f $i

    Write-Host "Add-AzureRmVMDataDisk -VM $vm -Name $name -DiskSizeInGB 16 -Lun $lun -Caching None -VhdUri $vhdUri -CreateOption Empty"

    $vm = Add-AzureRmVMDataDisk -VM $vm -Name $name -DiskSizeInGB 16 -Lun $lun -Caching None -VhdUri $vhdUri -CreateOption Empty


# uncomment when you are ready, this updates the VM on azure!
# Update-AzureRmVM -ResourceGroupName "md-test-stripe" -VM $vm

2. Create “new storage pool” from server manager with all the new disks you added

3. Create “new virtual disk” from powershell:

New-VirtualDisk -FriendlyName "sql-stripe" -StoragePoolFriendlyName "sql-stripe" -Interleave 65536 -NumberOfColumns 16 -ProvisioningType Fixed -ResiliencySettingName "Simple" -UseMaximumSize

4. Create “new volume” from server manager formatting in NTFS with allocation unit size set to 64KB