How to build desktop apps with Angular and Electron.js

In recent years, the development of web applications has become more and more important. This is mainly because applications can be used independently of the operating system via the browser and more and more data and services migrate to the cloud. In this case, the browser represents a kind of additional level of abstraction and ensures cross-platform access. In spite of everything, desktop applications are often requested. With the help of the Electron.js Framework , webapps can be read as native applications for a wide variety of systems. For example, we can build macOS, Windows, or Linux applications, and just add a few lines of code to our existing code.
Electron.js uses Node.js and Chromium for this purpose.
In principle, an instance of the Chromium browser is created that represents only the web application.

Let’s see how to use the Angular Framework to create a simple single-page application and then deliver it as a desktop application using the Electron.js Framework.

Install the required frameworks and generators

Prerequisite for the implementation is the installation of Node.js and NPM.
Afterwards we need the Angular-CLI for a quick setup of the web application. This is installed as a global NPM module as follows:

[cc lang=”javascript”]npm install -g @angular/cli[/cc]

We also want to use Electron.js under TypeScript later on. For this we still need the TypeScript compiler ( tsc ). In order to get the corresponding information about typing and thus also help from our editor, we install the typings package.
Later we can install the corresponding Typings for Electron.

[cc lang=”javascript”]npm install -g tsc typings[/cc]

Creating the Angular App

The next step is to create the app. The Subsequent command creates a new ng-electron-example folder, creates the framework for the app (the component prefix is elex in this case), and installs any needed dependencies.

[cc lang=”javascript”]ng new ng-electron-example -p elex cd ng-electron-example[/cc]

Now if we run npm start on the console and call the URL http://localhost:4200 in the browser, we should see that the app has already been started and the text “elex works!” Is displayed.

Install the required frameworks and tools for the desktop application

In order to create a desktop application from the existing webapp in the next step, we need a few more dependencies and tools.

We install these by calling NPM on the console:

[cc lang=”javascript”]npm install –save-dev copyfiles electron electron-packager rimraf typings[/cc]

Here are some brief explanations of the individual packages:

package use
copyfiles To copy files between folders
electron The Electron Framework
electron-packager A tool for creating system-specific electron program packages
rimraf Tool for deleting files and folders
typings A manager for installing typings


Configuration of Electron.js

At this point, let’s see how to use the Electron.js Framework with TypeScript.
To do this, we first create a new directory named electron and open it on the console:

[cc lang=”javascript”]mkdir electron && cd electron[/cc]

In the next step we want to find the typings we need. To do this, we enter the following command on the console:

[cc lang=”javascript”]typings search electron[/cc]

We now see a list of found typing entries. We need the Typings for electron and can now install them as follows:

[cc lang=”javascript”]typings install registry:dt/electron –save –global[/cc]

In the current directory, a folder typings is now created, which contains the appropriate specifications for typing.
Furthermore, the file typings.json created, which contains information about the currently installed Typings:

“globalDependencies”: {
“electron”: “registry:dt/electron#1.4.8+20170316233216”

Next we need the configuration file for TypeScript with information for the TypeScript compiler. For this we create the file tsconfig.json in the directory electron with the following content:

“compilerOptions”: {
“target”: “es5”,
“outDir”: “../dist”,
“module”: “commonjs”,
“moduleResolution”: “node”,
“sourceMap”: true,
“emitDecoratorMetadata”: true,
“experimentalDecorators”: true,
“removeComments”: false,
“noImplicitAny”: false,
“suppressImplicitAnyIndexErrors”: true
“exclude”: [

In the configuration, we indicated that the TypeScript compiler should generate JavaScript in the es5 standard, as it is fully implemented in almost all browsers. Furthermore, as output directory for the JavaScript code, we specify the dist directory that is generated by Angular, as long as we build the app for the live deployment (more on this later).
Further details on the individual configuration settings can be found in the official TypeScript documentation.

We have now made the most important preparations. Now let’s turn to the source code for creating the desktop app.
To do this, we create the electron file in the electron folder.
The source code needed for generation looks like this:

[cc lang=”javascript”]import { app, BrowserWindow } from ‘electron’;

class ElectronApp {
static app: Electron.App;
static BrowserWindow;
static mainWindow: Electron.BrowserWindow;

static main(app: Electron.App, browserWindow: typeof BrowserWindow) { = app;
ElectronApp.BrowserWindow = browserWindow;‘ready’, ElectronApp.onReady);‘window-all-closed’, ElectronApp.onWindowAllClosed);‘activate’, ElectronApp.onActivate);

// call when ready
private static onReady() {
// Create the window
ElectronApp.mainWindow = new BrowserWindow({
width: 1200,
height: 800,
resizable: false,
titleBarStyle: ‘hidden’,
title: ‘Angular Electron Example App’,
icon: `${__dirname}/favicon.ico`

// load index.html

// close the window
ElectronApp.mainWindow.on(‘closed’, ElectronApp.onClose);

// Quit after all windows has been closed
private static onWindowAllClosed() {
// keep app in application bar on OSX (because it’s common)
if (process.platform !== ‘darwin’) {; }

// fires if the window is closed
private static onClose() {
// Reset the window object to null
ElectronApp.mainWindow = null;

// recreate if activated again
private static onActivate() {
if (ElectronApp.mainWindow === null) { ElectronApp.onReady(); }


We call the static main method of the ElectronApp class and give it the two imports app and BrowserWindow , which Electron provides. Furthermore, we react to incoming events with the methods onReady() , onWindowAllClosed()
or onActivate.

The onReady method first creates a new one. For example, we set the size, the title and an icon.
A list of all available options can be found in the official documentation [5] .
About the specification in ElectronApp.mainWindow.loadURL we tell the Electron app the path to the homepage.
The last call in the onReady() method is executed when the window is closed.
The onClose() method overrides mainWindow with the value null .

In the onAllClosed() method, we specify what should happen when all windows are closed (in our case, only one exists).
At this point we check if the system is a macOS system and in this case call the .
This is a familiar practice with macOS because closing the application still keeps it in the Application Bar. Thus, this can be reactivated. This is done in the onActivate() method.

Now we want to customize the template and include the Webviewer provided by Electron:
For this we adapt the index.html file as follows:

The marriage of Angular and Electron.js

We have now made all the necessary preparations to create a native desktop app with Angular and Electron. Now we want to make sure that the app is generated and deployed for different operating systems.
For this we adapt the file package.json and extend it with script information and an indication of the main file of Electron.

// package.json
// …
“scripts”: {
// …
“start-el”: “npm run build && electron dist”,
“build”: “ng build –prod –base-href=. && copyfiles package.json dist && cd electron && tsc”,
“deploy”: “rimraf app && npm run build && electron-packager dist –all –electron-version=1.6.2 –overwrite –out=app && rimraf dist”,
“deploy-mac”: “rimraf app/*mas* && npm run build && electron-packager dist –platform=mas –arch=all –electron-version=1.6.2 –overwrite –out=app –icon src/assets/icon.icns && rimraf dist”,
“deploy-win”: “rimraf app/*windows* && npm run build && electron-packager dist –platform=win32 –arch=all –electron-version=1.6.2 –overwrite –out=app –icon src/assets/icon.ico && rimraf dist”,
“deploy-lin”: “rimraf app/*linux* && npm run build && electron-packager dist –platform=linux –arch=all –electron-version=1.6.2 –overwrite –out=app –icon src/assets/icon.ico && rimraf dist”,
// …
“main”: “electron.js”,
// …

The script build first creates the Angular app in the productive version. It is important to specify the option –base-href=. so that all files can be found after creation. The next step is to copy the NPM package configuration file to the dist directory. This is necessary, because here we specify the starting file for electron according to the script information ( “main”: “electron.js” ). Then the directory electron navigated and the TypeScript compiler is started ( tsc ).

The start-el script now calls the previously defined build script via npm run build and then starts electron with the contents of the dist folder.

The last scripts ensure that the app is generated as a ready-made bundle for the respective operating system. The icon specification sets an icon for the corresponding startup file (eg .exe under Windows). When specifying for macOS, note that we need an icon in icns format:

[cc lang=”javascript”]src/assets/icon.icns[/cc]

With the –out switch, we set the folder app as output directory. –platform we define the respective target platform and use –arch the architecture (eg x86 or x64). the specification all ensures that the app is generated for multiple platforms or architectural forms.

Since our directory is under version control we should still exclude the app folder. To do this, we’ll .gitignore file and add the following lines:

# …
# Deployed Apps

Finished! You have now learned how to use Angular and Electron to create desktop applications for a variety of operating systems. Of course, this was just a brief introduction and you can take advantage of much more functionality from Angular and Electron.

Recent Articles


Related Stories

Leave A Reply

Please enter your comment!
Please enter your name here