Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon

How to build a cross-platform desktop application with Node.js and Electron

Save for later
  • 9 min read
  • 14 Oct 2015

article-image

Do you want to make a desktop application, but you have only mastered web development so far? Or maybe you feel overwhelmed by all of the different API’s that different desktop platforms have to offer? Or maybe you want to write a beautiful application in HTML5 and JavaScript and have it working on the desktop? Maybe you want to port an existing web application to the desktop?

Well, luckily for us, there are a number of alternatives and we are going to look into Node.js and Electron to help us get our HTML5 and JavaScript running on the desktop side with no hiccups.

What are the different parts in an Electron application

Commonly, all of the different components in Electron are either running in the main process (backend) or the rendering process (frontend). The main process can communicate with different parts of the operating system if there’s a need for that, and the rendering process mainly just focuses on showing the content, pretty much like in any HTML5 application you find on the Internet. The processes communicate with each other through IPC (inter-process communication), which in Node.js terms is just a super simple event emitter and nothing else. You can send events and listen for events.

You can get the complete source code from here for this post.

Let's start working on it

You need to have node.js installed and you can install it from https://nodejs.org/. Now that you have Node.js installed you can start focusing on creating the application. First of all, create an empty directory where you will be placing your code.

# Open up your favourite terminal, command-line tool or any other alternative as we'll be running quite a bit of commands

# Create the directory
mkdir /some/location/that/works/in/your/system

# Go into the directory
cd /some/location/that/works/in/your/system

# Now we need to initialize it for our Electron and Node work
npm init

NPM will start asking you questions about the application we are about to make. You can just hit Enter and not answer any of them if you feel like it. We can fill them in manually once we know a bit more about our application. Now we should have a directory structure with the following files in it:

package.json

And that's it, nothing else. We'll start by creating two new files in your favorite text editor or IDE. The files are (leave the files empty):

main.js
index.html

Drop all of the files into the same directory as the package.json is in for easier handling of everything for now. Main.js will be our main process file, which is the connecting layer to the underlying desktop operating system for our Electron application. At this point we need to install Electron as a dependency for our application, which is really easy. Just write:

npm install --save electron-prebuilt

Alternatively if you cloned/downloaded the associated Github repository you can just go into the directory and write:

npm install

This will install all dependencies from package.json, including the prebuilt-electron.

Now we have Electron's prebuilt binaries installed as a direct dependency for our application and we can run our application on our platform. It's wise to manually update our package.json file using the npm init command generated for us. Open up package.josn file and modify the scripts block to look like this (or if it's missing, create it):

"main": "main.js",
"scripts": {
   "start": "electron ."
},

The whole package.json file should be roughly something like this (taken from the tutorial repo I linked earlier):

{
"name": "",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
   "start": "electron ."
},
"repository": {
},
"keywords": [
],
"author": "",
"license": "MIT",
"bugs": {
},
"homepage": "",
"dependencies": {
   "electron-prebuilt": "^0.25.3"
}
}

The main property in the file points to the main.js and the scripts sections start property tells it to run command "Electron .", which essentially tells Electron to digest the current directory as an application and Electron hardwires the property main as the main process for the application. This means that main.js is now our main process, just like we wanted.

Main and rendering process

We need to write the main process JavaScript and the rendering process HTML to get our application to start. Let's start with the main process, main.js. You can also find all of the code below from the tutorial repository here. The code has been peppered with a good amount of comments to give a deeper understanding of what is going on in the code and what different parts do in the context of Electron.

// Loads Electron specific app that is not commonly available for node or io.js
var app = require("app");
// Inter process communication -- Used to communicate from Main process (this)
// to the actual rendering process (index.html) -- not really used in this example
var ipc = require("ipc");
// Loads the Electron specific module or browser handling
var BrowserWindow = require("browser-window");
// Report crashes to our server.
var crashReporter = require("crash-reporter");

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the javascript object is garbage collected
var mainWindow = null;

// Quit when all windows are closed.
app.on("window-all-closed", function() {
   // OS X specific check
   if (process.platform != "darwin") {
       app.quit();
   }
});

// This event will be called when Electron has done initialization and ready for creating browser windows.
app.on("ready", function() {
   crashReporter.start();
   // Create the browser window (where the applications visual parts will be)
   mainWindow = newBrowserWindow({ width: 800, height: 600 });

   // Building the file path to the index.html
   mainWindow.loadUrl("file://" + __dirname + "/index.html");

   // Emitted when the window is closed.
   // The function just deferences the mainWindow so garbage collection can
   // pick it up
   mainWindow.on("closed", function() { mainWindow = null; });
});

You can now start the application, but it'll just start an empty window since we have nothing to render in the rendering process. Let's fix that by populating our index.html with some content.

Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
<!DOCTYPE html>
<html>
   <head>
       <title>Hello Tutorial!</title>
   </head>
   <body>
       <h2>Tutorial</h2>
       We are using node.js <script>document.write(process.version)</script> and Electron <script>document.write(process.versions["electron"])</script>.
   </body>
</html>

Because this is an Electron application we have used the node.js/io.js process and other content relating to the actual node.js/io.js setup we have going. The line document.write(process.version) actually is a call to the Node.js process. This is one of the great things about Electron: we are essentially bridging the gap between the desktop applications and HTML5 applications. Now to run the application.

npm start

There is a huge list of different desktop environment integration possibilities you can do with Electron and you can read more about them from the Electron documentation at http://electron.atom.io/.

Obviously this is still far from a complete application, but this should give you the understanding on how to work with Electron, how it behaves and what you can do with it.

You can start using your favorite JavaScript/CSS frontend framework in the index.html to build a great looking GUI for your new desktop application and you can also use all Node.js specific NPM modules in the backend along with the desktop environment integration. Maybe we'll look into writing a great looking GUI for our application with some additional desktop environment integration in another post.

Packaging and distributing Electron applications

Applications can be packaged into distributable operating system specific containers. For example, .exe files allow them to run on different hardware. The packaging process is fairly simple and well documented in the Electron's documentation and it is out of the scope for this post but worth the look if you want to package your application. To understand more of the application distribution and packaging process, read the Electrons official documentation on it here.

Electron and it's current use

Electron is still really fresh and right out of GitHub's knowing hands, but it's already been adopted by quite few companies for use and there are number of applications already built on top of it.

Companies using Electron:

  • Slack
  • Microsoft
  • Github

Applications built with Electron or using Electron

  • Visual Studio Code - Microsofts Visual Studio code
  • Heartdash - Hearthdash is a card tracking application for Hearthstone.
  • Monu - Process monitoring app
  • Kart - Frontend for RetroArch
  • Friends - P2P chat powered by the web

Final words on Electron

It's obvious that Electron is still taking its first baby steps, but it's hard to deny the fact that more and more user interfaces will be written in different web technologies with HTML5 and this is one of the great starts for it. It'll be interesting to see how the gap between the desktop and the web application develop as time goes on and people like you and me will be playing a key role in the development of future applications.

With help of technologies like Electron the desktop application development just got that much easier.

For more Node.js content, look no further than our dedicated page!

About the author

Mika Turunen is a software professional hailing from the frozen cold Finland. He spends a good part of his day playing with emerging web and cloud related technologies, but he also has a big knack for games and game development. His hobbies include game collecting, game development and games in general. When he's not playing with technology he is spending time with his two cats and growing his beard.