July 17, 2019

Creating a Desktop App Powered by Electron and Angular

by Jay Raj

Creating a Desktop App Powered by Electron and Angular

In this tutorial, you'll learn how to create a desktop app powered by Electron and Angular. The tutorial assumes the reader to have a basic understanding of the Angular web application framework.

The source code from this tutorial is available on GitHub.

Introduction to Electron

HTML, CSS, and JavaScript is a powerful combination which can be used to create not only web applications but also mobile apps. Using the Electron framework, you can utilize the same combination of web technology to create cross-platform desktop applications for different operating systems.

From the official documentation:

The Electron framework lets you write cross-platform desktop applications using JavaScript, HTML and CSS. It is based on Node.js and Chromium and is used by the Atom editor and many other apps.

What You'll Build

In this tutorial, you'll be creating a simple expense manager web application using Angular. Once you have the application up and running, you'll make use of the Electron framework to port the web app to a cross-platform desktop app.

Creating an Expense Manager App Using Angular

Start by installing the Angular CLI using Node Package Manager (npm).

npm install -g @angular/cli

Once you have the Angular CLI installed, you can use it to create an Angular web app. Start by creating a project folder called electron-app. Inside the project folder, create the Angular app.

cd electron-app
ng new expense-manager

The above command will prompt for routing and type of style sheets for the project. Select no routing and CSS respectively.

You'll be using Bootstrap for styling the Angular web application. Install both jQuery and Bootstrap using npm.

npm  install bootstrap jquery

Once both are installed, you need to include the Bootstrap script and style reference in the angular.json file.

Add the script and style reference under architect->build->options.

"styles": [
  "src/styles.css",
  "node_modules/bootstrap/dist/css/bootstrap.min.css"
 ],
 "scripts": [
   "node_modules/jquery/dist/jquery.min.js",
   "node_modules/bootstrap/dist/js/bootstrap.min.js"
 ]

Add the following HTML code to the src/app/app.component.html file.

<div class="container">
    <div class="py-5 text-center">
   	 <h2>Expense Manager</h2>
    </div>
    <div class="row">
   	 <div class="col-centered">
   		 <h4 class="d-flex justify-content-between align-items-center mb-3">
    	<!-- Button trigger modal -->
    	<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
      	Add Expense
    	</button>

    	<!-- Modal -->
    	<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
      	<div class="modal-dialog" role="document">
        	<div class="modal-content">
          	<div class="modal-header">
            	<h5 class="modal-title" id="exampleModalLabel">New expense</h5>
            	<button type="button" class="close" data-dismiss="modal" aria-label="Close">
              	<span aria-hidden="true">&times;</span>
            	</button>
          	</div>
          	<div class="modal-body">
            	<div class="input-group mb-3">
              	<input type="text" class="form-control" placeholder="Expense title">
            	</div>
            	<div class="input-group mb-3">
              	<input type="number" class="form-control" placeholder="Expense amount">
            	</div>

          	</div>
          	<div class="modal-footer">
            	<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
            	<button type="button" class="btn btn-primary">Save changes</button>
          	</div>
        	</div>
      	</div>
    	</div>
   	 
  	</h4>
   		 <ul class="list-group mb-3">
   			 <li class="list-group-item d-flex justify-content-between lh-condensed">
   				 <div>
   					 <h6 class="my-0">Farm fresh vegetables</h6>
   				 </div> <span class="text-muted">$12</span>
   			 </li>
   			 <li class="list-group-item d-flex justify-content-between lh-condensed">
   				 <div>
   					 <h6 class="my-0">Organic Eggs</h6>
   				 </div> <span class="text-muted">$8</span>
   			 </li>
   			 <li class="list-group-item d-flex justify-content-between lh-condensed">
   				 <div>
   					 <h6 class="my-0">Beer</h6>
   				 </div> <span class="text-muted">$5</span>
   			 </li>
   		 </ul>
   	 </div>
    </div>
</div>

Save the above changes and try running the Angular app with npm start. You will have the Expense manager UI running. Clicking the modal Add Expense shows a pop up to add an expense.

Expense Manager App

You just created the Angular app UI which is sufficient for checking out how Angular and Electron work together. As an extra exercise, feel free to add the back end implementation of the Expense manager app before moving forward.

Protect your Angular App with Jscrambler

How to Use Angular in Electron

Now, since you have the Angular web app up and running, let's see how you can use it in Electron.

To use the Angular web app, you need to build the app. Before building the app, you need to add two configurations to the angular.json file.

In architect->build->options in the angular.json file add the following options:

"outputPath": "../dist",
"baseHref": "./"

The outputPath tells Angular where to put the build output and baseHref indicates the root folder where to look for scripts and images.

Save the above changes and build the Angular app from the Angular project directory expense-manager.

npm run build

Once the above process finishes, the Angular build files will be in a dist folder outside the Angular source code.

Setting Up the Desktop App Using Angular and Electron

To get started with the Electron framework, initialize the Node project inside the electron-app folder.

cd electron-app
npm init

Once the Node project has been initialized, install the Electron framework.

npm i -D [email protected]

Create a file called app.js inside electron-app. Require BrowserWindow and app from Electron.
Using BrowserWindow, you'll create a new desktop windows screen and initialize it when the Electron app is ready.

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

let win

async function createWindow () {
  // Create the browser window.
  win = new BrowserWindow({
	width: 800,
	height: 600
  })
 
  try{
	let res = await win.loadFile(__dirname + "/dist/index.html")
  } catch(error){
  	console.log(error);
  }
 
  win.on('closed', () => {
	win = null
  })
}

app.on('ready', createWindow)

As seen in the above code, you have loaded the Angular build's index.html file inside the newly created window.

Save the changes and run the app using npm start. You will have the Angular app rendered inside a window as a desktop application.

Angular Electron App

Conclusion

In this tutorial, you learned how to use the power of HTML, CSS and JavaScript to create cross-platform desktop apps using Electron framework.

There are a number of reasons to start using Electron for writing Desktop applications. In fact, many well-known apps, like Slack desktop and WordPress desktop are built using this framework. The best part, if you are a web developer, you don’t have to learn anything new to write a desktop app using Electron.

On a personal front, I think Electron is great. Visual Studio Code is an editor that I use on a daily basis and it’s based on Electron and it’s very powerful. Of course, native developers might have a different opinion about Electron.

How was your experience learning to write cross-platform desktop applications using Electron? Let us know thoughts by tweeting to @Jscrambler.

What you learned here is only the tip of the iceberg. For more detailed info on Electron, I recommend reading the official documentation.

Lastly, if you want to learn how you can secure your Angular source code against theft and reverse-engineering, be sure to check our guide.