You are here

Building Cross-Platform Software is Easy

That’s right, I said it. And I stand by it. Building cross-platform software can be easy if you know how to do it. Sure, it used to be impossible. You had to decide on your platform upfront and build to that platform. Or build two completely different platforms. But these days, you can build your app and then decide which platforms to deploy it to.

How do I know? I have a recent client project to thank for this insight. My client wanted to create an interactive web game that also ran locally on sales reps’ Windows computers when they were not connected to the internet. The game was a fairly complicated 3D experience so the client wanted to avoid having to build it twice, once for web and once for desktop.

My teammates and I thought about our options. How could we solve this problem? Since the game required at least 1000px we didn’t consider mobile. But what about Unity, Unreal or Pure Web? Then it hit us: let’s try Electron.

Introducing Electron

Electron is a framework for creating native applications with web technologies like JavaScript, HTML, and CSS. Electron combines Chromium and Node into a single runtime for building custom desktop web applications that also have access to Node so it has an application-like experience and can do things that web browsers normally can't do. It offers some other appealing features, too.

Electron is Compatible with Mac, Windows, and Linux

Electron uses Chromium and Node.js

Electron is open source

So who uses Electron? Most likely, you do. For sure, I do. In fact, half the apps I have running daily use Electron. For instance, Microsoft (Visual Studio Code), Slack, Postman, Github desktop, and Figma.

Electron Components and Features

Components

Chromium is an open-source browser project that forms the basis for the Chrome without some bells and whistles.

Node is a C program for running JavaScript, though it isn’t JavaScript. JavaScript is great for sending instructions to a C program that can be carried out in your OS. And JS is easier to code.

Features

Automatic updates

Native menus & notifications

ES6 Support through V8

MouseEvent.getModifierState() (Alt, Control, Shift)

CSS.escape()

Fetch API Streaming (beats XHR)

Why is Electron so great? For one, you can’t tell the difference between Electron and a native app. For another, Electron is actively maintained. The current release is v2, however v3 is in beta (Chromium 66 and Node 10). See the activity below:

Here’s How Electron Works

Electron uses Chromium for displaying web pages. Chromium's multi-process architecture is also used. Each web page in Electron runs in its own process, called the renderer process. In normal browsers, web pages usually run in a sandboxed environment and are not allowed access to native resources. Electron uses Node.js APIs in web pages allowing lower-level operating system interactions.

Electron provides a runtime to build desktop applications with JavaScript. (Electron takes a main.js file defined in your package.json file and executes it.) In Electron, the process that runs package.json's main script is called the main process. The script that runs in the main process can display a GUI by creating web pages. An Electron app always has one main process, but never more.

Electron is truly cross-platform. Electron API only adds support for features that can work on all platforms. NodeJS is supported by Mac, Windows and Linux. Chromium is also cross-platform. Electron implements a 'Tray' API that is generic enough to work as a Windows 'system tray' and Mac OS 'menubar'.

Building Your Electron Application

For our project, we took our html, js and webgl code and built it as an application for Windows, Mac and Linux with Electron. In general, the process is as simple using Electron Packager (https://github.com/electron-userland/electron-packager). Set up your package.json scripts file to be able to run the following commands. Here's an example.

Build the application:

npm run release:build

Release the application:

npm run release:mac
npm run release:win (I have installed “brew install wine” to build on a mac!)
npm run release:linux

We now have an application built for each platform. Here are a few screenshots of the demo game we created with Electron, running on Mac, Windows (large touchscreen) and RaspberryPi.

Windows on a large touchscreen

On my local Mac

Running on an rPi

Electron Makes Updating a Breeze

When developing games previously, we had to build an updater for our applications or require the user to pull new code. Have you ever asked a non-technical person to use git? Please. Or, we’ve had to complete the dreaded install using a thumb-drive tactic.

We’ve all been there. But that’s in the past. With Electron, updating is much easier. Why? Electron AutoUpdate requires just two lines of code. The way it should be.

(You can find more information on AutoUpdate here. Note that IPC modules are the standard way to send messages between processes in Electron. You can learn more about them here.)

What About Mobile?

Though we didn’t need a mobile experience for this particular client, we still needed a solution for others. We looked at Electron, but sadly it doesn’t help in this situation. Fortunately, it is possible to create a hybrid application using a native packager like Cordova, which wraps your html/js/css browser WebView into a native app and displays it. Cordova Plugins add the native functionality to the app.

The Takeaway

Today, there are a few cross-platform solutions that work pretty well. I’ve found using Electron for Mac/Windows and Linux (and Cordova for mobile) to be a super easy way to bring a web application to every platform. My client was pretty happy too. Using Electron saved development time and effort while allowing my team to deliver a quality experience. You should explore Electron for your next cross-platform project.

Interested in reading more web development content? Check out my other blogs here.