Electron is an open-source project that allows us to create desktop applications using HTML, CSS, and JavaScript. With Electron, we can use web technologies to create desktop applications.

In this article, we will learn how to build a simple calculator desktop application using Electron. The application will have only basic functionalities like Add, Subtract, etc.

We need to install node.js before proceeding to create the application.

Setting up the project structure

The Electron does not force us to have a particular directory structure while creating the application.

Set up project structure

Create a directory with the name calculator. This directory will be the root directory of our Electron application.

Navigate inside the created folder and create the following files.

touch app/index.html 
touch app/renderer.js 
touch app/styles.css 
touch app/app.js

This will create a folder called app inside our calculator folder. This app folder will have:

  • index.html: The Electron application home page.
  • styles.css: CSS styling for the Electron application.
  • app.js: This file contains the configuration details of the Electron application.
  • renderer.js: This javascript file contain all the application functionalities.

Setting up the package.json file

Within the application directory calculator, run the below command.

npm init

This will set up our node package by creating a package.json file. Command will also prompt us to enter some basic details about the application.

create electron app with node.

Notice that we have set the entry point of the application to app/app.js.

Installing the Electron

To download and install Electron, execute the below command from the application’s root directory(calculator).

npm install electron –-save-dev

This will download and install the latest Electron in our project’s node_modules directory.

Creating  electron app on windows

Update package.json file by adding the following value under the scripts JSON field.

"start": "electron ."

This will inform node that upon running the npm start, it should execute the “electron .” command.

The complete update package.json file should look like below.

{
  "name": "calculator",
  "version": "1.0.0",
  "description": "Simple Calculator",
  "main": "./app/app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start" : "electron ."
  },
  "author": "Arun",
  "license": "ISC",
  "devDependencies": {
    "electron": "^8.2.5"
  }
}

Creating the calculator application

Navigate inside the app directory of the application.

Define main process of Electron app

Open the file app.js.

This file is the starting point of our Electron application. Once we execute the “npm start” command, the content of this file is executed. This file is considered as the main process of the Electron application.

Add the following content into the app.js file.

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

function createWindow () {
	let mainWindow = new BrowserWindow({
		width: 300,
		height: 460,
		icon:'app/icon.png',
		webPreferences: {
		  nodeIntegration: true
		}
	  });
	mainWindow.loadFile('./app/index.html');
	mainWindow.setMenuBarVisibility(false);
	mainWindow.setResizable(false);
}
app.whenReady().then(createWindow);
  • We have imported the Electron’s app and BrowserWindow modules.
  • The app module is the basic Electron module that handles the life cycle and application configuration of the Electron application.
  • BrowserWindow is a renderer process. We can use this module to load our HTML, CSS, and JS files into our Electron application window.
  • We are calling the createWindow function on the application’s ready event by using app.whenReady().
  • We have initialized our BrowserWindow module by setting the width, height, etc.
  • We are loading index.html file into the created window.
  • We have disabled resizing of the window and hidden default menu bar.

Adding the calculator UI

We need to add the required HTML structure and CSS styling to our Electron calculator application.

Add the HTML structure

Add the following content to the index.html file. This file contains the HTML content for our Electron calculator application.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self';script-src 'self' 'unsafe-inline';connect-src *">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>SIMPLE CALCULATOR</title>
<link rel="stylesheet" href="./styles.css" type="text/css">
</head>
<body>
<div class="container">
    <div class="calculator">
      <div class="calculator_display">0</div>
      <div class="calculator_keys">
        <button class="key-operator">+</button>
        <button class="key-operator">-</button>
        <button class="key-operator">x</button>
        <button class="key-operator">/</button>
        <button>7</button>
        <button>8</button>
		<button>9</button>
		<button>4</button>
		<button>5</button>
		<button>6</button>
		<button>1</button>
		<button>2</button>
		<button>3</button>
		<button>0</button>
        <button>.</button>
        <button>AC</button>
        <button class="key-equal">=</button>
      </div>
    </div>
</div>
<script>
 require('./renderer');
</script>
</body>
</html>

We have used the node’s require function to load the javascript file that contains our calculator’s functionalities by using <script> tag.

Adding style to the application

Open the styles.css file and add the following CSS content.

body {
  margin: 0;
}
button {
  border: 0;
  border-radius: 0;
  background-color: transparent;
  font-size: inherit;
  font-family: inherit;
  font-weight: inherit;
  outline: none;
  appearance: none;
  text-align: left;
}
button:hover,
button:active,
button:focus {
  outline: none;
}

:root {
  font-family: Helvetica, Arial, sans-serif;
}

.calculator_display {
  background-color: #222222;
  color: #fff;
  font-size: 1.5em;
  padding: 0.45em 0.45em;
  text-align: right;
}

.calculator_keys {
  background-color: #999;
  display: grid;
  grid-gap: 1px;
  grid-template-columns: repeat(4, 1fr);
}

.calculator_keys > * {
  background-color: #fff;
  padding: 0.5em 0.50em;
  position: relative;
  text-align: center;
}

.calculator_keys > *:active::before,
.calculator_keys > .is-depressed::before {
  background-color: rgba(0, 0, 0, 0.2);
  bottom: 0;
  box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.5) inset;
  content: "";
  left: 0;
  opacity: 0.3;
  position: absolute;
  right: 0;
  top: 0;
  z-index: 1;
}

html {
  font-size: 180%;
  font-weight: 300;
  line-height: 1.64;
}

body {
  align-items: center;
  background-color: black;
  justify-content: center;
}

.container {
  max-width: 20em;
}

.calculator {
  margin-left: auto;
  margin-right: auto;
  max-width: 17em;
}

.key-operator {
  background-color: silver;
}

.key-equal {
  background-color: orange;
  grid-column: -2;
  grid-row: 2 / span 4;
}

Adding the functionalities to calculator app

Open the renderer.js and add the following content.

class Calculator {
    constructor(field1, field2, isSecondVal) {
        this.field1 = field1;
        this.field2 = field2;
	this.isSecondVal = isSecondVal;
	this.operation = '+';
    }
}
var isNumber = false;
const calculator = new Calculator('', '', false);
const buttons = document.querySelectorAll('button');
const display = document.querySelector('.calculator_display');

for (var i = 0; i < buttons.length; i++) {
  buttons[i].addEventListener('click', function() {
	checkNumber(this.innerHTML);
	if(isNumber || ('.' === this.innerHTML)){
		if(calculator.isSecondVal === false) {
				if(calculator.field1 === '0'){
					calculator.field1 = ('.' === this.innerHTML) ? ('0' + this.innerHTML) : this.innerHTML;
				} else if(calculator.field1.length < 8){
					calculator.field1 = calculator.field1 + this.innerHTML;
				}
				display.innerText = calculator.field1;
		} else {
			if(calculator.field2 === '0') {
				calculator.field2 = this.innerHTML;
			}
			else if(calculator.field2.length < 8){
				calculator.field2 = calculator.field2 + this.innerHTML;
			}
			display.innerText = calculator.field2;
		}
	} else {
		switch(this.innerHTML) {
			case '+':
			case '-': 
			case 'x':
			case '/':
				calculator.operation = this.innerHTML;
				calculator.isSecondVal = true;
				break;
			case 'AC':
				clear();
				display.innerText = 0;
				break;
			default:
				calculate();
		}
	}
  });
}

function calculate(){
	var value1 = parseFloat(calculator.field1);
	var value2 = parseFloat(calculator.field2);
	var result;
	switch (calculator.operation){
		case '-':
			result = value1 - value2;
			break;
		case 'x':
			result = value1 * value2;
			break;
		case '/':
			result = value1 / value2;
			break;
		default:
			result = value1 + value2;
			break;
	}
	parseResult(result);
	clear();
}

function parseResult(val){
	if(isInteger(val)){
		display.innerText = val;
	} else {
		display.innerText = val.toFixed(3);
	}
}

function clear(){
	calculator.field1 = '0';
	calculator.field2 = '0';
	calculator.isSecondVal =false;
}

function isInteger(value) {
  return /^\d+$/.test(value);
}

function checkNumber(number){
	var regex = /^\d+$/;
	isNumber = regex.test(number);
};
  • We have created a Calculator class that holds the input values of the calculator. It also contains the second input value indicator and default operation.
  • The variable isNumber is used to determine if the button clicked is a number or not.
  • We have used javascript query selector to select all the button elements and the display element that displays input and result value of the calculator.
  • We are listening to the click event on any of the buttons and perform the action based on the user input.
  • The calculate() function calculates the result value on click of any arithmetic operation.
  • The clear() function clears all the Calculator fields and initializes the calculator.
  • The checkNumber() function is used to determine if the button text is a number or not.
  • The parseResult() function will parse the float result by fixing the result decimal point to 3.

Testing the application

To start the application, run the following command from the application’s root folder(calculator).

npm start
electron calculator app.

Conclusion

In this article, we learned how to create a simple calculator desktop application using Electron, HTML, CSS, and JavaScript.

Even though the application supports basic functionalities, we can improve a few functionalities like:

  • Support for negative user inputs.
  • Preventing the user from inputting multiple dots(.). etc.

The code is available on GitHub.

You may also be interested in