kinney_1_00 By Steve Kinney

This article is excerpted from Chapter 1 of Electron in Action

One of the big things that the web has going for it is ubiquity. It’s an amazing platform for creating collaborative applications that can be accessed from a wide range of devices running a number of different operating systems. That said, there are entire classes of applications that can’t be built in the browser environment. Web applications can’t access the file system. They can’t execute code that isn’t written in JavaScript. They can’t hook into many of the operating system APIs that desktop applications can. Most web applications aren’t available when there isn’t a reliable Internet connection.

For a long time, building for the desktop has involved adopting a completely different skill set. Many of us don’t have the bandwidth to take on the long learning curve necessary for learning new languages and frameworks. With Electron, we can leverage our existing skills as a web developer to build applications that have many of the capabilities of a native desktop application.


What is Electron?

Electron is a runtime that allows you to create desktop applications with HTML5, CSS, and JavaScript. It’s an open source project started by Cheng Zhao (a.k.a.zcbenz), an engineer at Github. Previously called Atom Shell, Electron is the foundation for Atom, a cross-platform text editor by Github built with web technologies.

You may have heard of or used Apache Cordova or Adobe PhoneGapfor building web applications—wrapped in native shells—for mobile operating systems like iOS, Android, and Windows Phone.If so, then it might be helpful to think of Electron as a similar tool for building desktop applications instead of mobile applications.

Electron combines the Chromium Content Module and Node.js runtimes. It allows developers to build graphical user interfaces (GUIs) with web pages as well as access native operating system capabilities on OS X, Windows, and Linux through an OS-agnostic API.

Chromium and Node are both wildly popular application platforms in their own right and both have been used independently to create ambitious applications. Electron brings the two platforms together to allow you to use JavaScript to build an entirely new class of application. Anything you can do in the browser, you can do with Electron. Anything you can do with Node, you can do with Electron. Together, we can build applications that take advantage of both platforms and build applications that wouldn’t otherwise be possible on just one.

The exciting part is what you can do with the two technologies together. That’s what this book is all about. Electron is not only a great choice for building web applications that behave like native desktop applications; it’s also a great choice for building a GUI around Node applications that would otherwise be limited to only a command-line interface. Having access to Node.js allows developers to use CommonJS modules without the need for a build system like webpack or Browserify—although you could certain use one of those tools if you wanted to.

What is an example of an application that wouldn’t be feasible in the browser? Let’s say that we wanted to build an application that allowed us to view and edit a folder of images on our computer. Traditional browser applications cannot access the file system. They wouldn’t be able to access the directory of photographs, load any of the photographs in the directory, or save any of the changes that you made within the application. With Node, we’d be able to implement all of those features, but we wouldn’t be able to provide a graphical user interface, which would make our application difficult to use for the average user. By combining the browser environment with Node, Electron allows us to create an application where we can both open and edit photographs as well as provide a UI for doing so.


kinney_1_01

Figure 1.1 Electron combines the core web browsing component of Chromium with the low-level system access of Node.


Electron isn’t a complicated framework. It’s a simple runtime. Just like you might use node from the command line, you can run Electron applications using the electron command line tool. There aren’t a lot of conventions that you’ll need to learn in order to get started and you’re free to structure your application however you’d like—although, we’ll provide some tips and best practices throughout this book.

What is the Chromium Content Module?

Chromium is the open source version of Google’s Chrome web browser. It shares much of the same code and features with a few minor differences and different licensing. The Content Module is the core code that allows Chromium to render web pages in independent processes and utilize GPU acceleration. It includes the Blink rendering engine and the V8 JavaScript engine. The Content Module is what makes a web browser a web browser. It’s the foundation for building a full-featured web browser.It handles fetching and rendering HTML from a web server, loading any referenced CSS and JavaScript, styling the page accordingly, and executing the JavaScript.

The easiest way of thinking about the Content Module is to consider what it doesn’t do. The Content Module does not include support for Chrome Extensions. It doesn’t handle syncing your bookmarks and history with Google’s cloud services. It doesn’t handle securely storing our saved passwords or automatically filling them in for you when you visit a page. It doesn’t detect if a page was perhaps written in another language and subsequently call on Google’s translation services for assistance.It justincludes just the core technologies required to render HTML, CSS, and JavaScript.


Who is using Electron?

Electron is being used by a number of companies large and small to build desktop applications. As we discussed earlier, it was originally developed as the foundation for Github’s Atom text editor. Atom needed access to the file system in order to fulfill its duties as a text editor. Similarly, other companies have also turned to Electron as the foundation of their text editing applications. New projects built on top of Electron are being released every day as companies and developers see the value in being able to build products that leverage the power afforded to desktop applications while still maintaining the Web’s intrinsic platform agnosticism.

Facebook released Nuclide as a package on top of Atom that turns the text editor into a full-fledged IDE with first-class support for working with React Native, Hack, and Flow projects. Microsoft is also using Electron for their cross-platform Visual Studio Code editor. Visual Studio Code runs on OS X, Windows, and Linux.

You can build more than just text editors with Electron. Slack, the popular messaging application leverages Electron for their Windows and Linux versions. Nylas uses Electron for their N1 email client, which is designed to look beautiful across all of the major platforms. It also supports a JavaScript plugin architecture that allows third-party developers to add features and extend the user interface.

Brave—a new browser focused on speed and security by Brendan Eich, the creator of JavaScript—is itself built on top of Electron. That’s right, you can even use web technologies to build a web browser.


What do I need to know?

Let’s start with what you don’t need to know. This book is for web developers who want to use their existing skill set to create desktop applications that wouldn’t be possible inside of the traditional browser environment.

You should be comfortable with writing JavaScript, HTML, and CSS but by no means do you need to be an expert. I won’t be covering variables or conditionals in this book but, if you’re familiar with general language features of JavaScript, then you probably have the requisite skills to follow along. It’s also helpful if you’re familiar with some of the conventions and patterns from Node.js, such as how the module system works for instance. We’ll explore these concepts as we come across them.


Why should I use Electron?

When we’re writing applications for the web browser, we have to be both conservative in what technologies we choose to use and cautious in how we write our code. This is because—unlike many server-side situations—we are writing code that will be executed on someone else’s computer.

Our users could be using the latest version of a modern browser like Chrome or Firefox or they could be using an outdated version of Internet Explorer. We have little-to-no say in where our code is being rendered and executed. We have to be ready for anything.

This typically involves writing code for the lowest common denominator of features that have the widest support across all of the versions of all of the browsers in use today. This means that even if there is a better, more efficient, or generally more appealing solution to a problem, we might not be able to usethat approach. When we decide to reach for a modern browser feature, we typically need to implement a contingency plan of graceful fallbacks, feature detection, and progressive enhancement that adds a non-trivial amount of friction to our development workflow.

Electron allows us to use cutting edge web platform features as it includes a relatively recent version of Chromium. Generally speaking, the version of Chromium in Electron is about one to two weeks behind the most recent stable release—which come out every six weeks. Electron typically includes new versions of Node.js about a month after they’re released. This is because one of the most compelling reasons to update Node.js is to get the most recent version of V8. Electron already includes a modern build of V8 from Chromium. Electron can afford to wait for minor bug fixes before upgrading to the latest version of Node.

Leveraging your existing skill set

If you’re like me, then you probably have much more experience building web applications than desktop applications. You’d love to add the ability to create desktop applications to your set of tools, but you don’t have the bandwidth to learn not just a new programming language, but likely a new framework as well.

Learning a new language or framework is an investment that is not to be taken lightly. As web developers we’re used to writing applications that work equally well for all of our users—even if that means fighting with idiosyncrasies of a particular browser or screen size. But, when we’re contemplating building traditional desktop applications, we’re not just talking about learning one language and framework. We’re looking at learning at least three different languages and frameworks if we want to target OS X, Windows, and Linux.

Electron allows individuals and small teams to offer desktop applications in situations where they wouldn’t otherwise be able to. For a small team, hiring a developer skilled in building applications for each of those platforms may not be an option. Electron allows us to leverage our existing skill set and deploy our application to all of the major platforms.With Electron, we can support multiple operating systems with less effort than we’re normally used to in order to supporting multiple browsers.

Access to native operating system APIs

Electron applications are a lot like any other desktop application. They live in the file system with the rest of your native applications. They sit in the dock in OS X or taskbar in Windows and Linux where all of the other native applications hang out. Electron applications can trigger native open and save file dialogs. These dialogs can be configured to only allow the operating system to select files with a particular file extension, whole directories, or multiple files at the same time. We can drag files onto our Electron applications and trigger different actions.

Additionally, Electron applications can set custom application menus just like any other application. They can create custom context menus that spring into action when the user right-clicks from within the application. We can use Chromium’s Notification API to trigger system-level notifications. They can read from the system clipboard and write text, images, and other media to it as well.


kinney_1_02

Figure 1.2 Electron allows us to create custom application menus.


Unlike traditional web applications, Electron applications are not limited to the browser. We can create applications that live in the menu bar or the system tray. We can even register global shortcuts to trigger these applications or any of their abilities with a special keystroke from anywhere in the operating system.


kinney_1_03

Figure 1.3. We can create application that lives in the operating system’s menubar or system tray.


Offline First

As anyone who has ever taken a computer on a transcontinental flight can attest, most browser-based web applications aren’t much good without a connection to the Internet. Even advanced web applications using any of the popular client-side frameworks like Ember, React, or Angular typically need to connect to a remote server to download their assets.

Electron applications have already been downloaded to the user’s computer. Typically, they load a locally-stored HTML file. From there, they can request remote data and assets if there is a connection available. Barring some kind of special circumstance—you’re building a chat client, for example—Electron applications work just as well offline as any other application.


How does Electron work?

Electron applications consist of two types of processes: the main process and zero or more renderer processes. Each process plays a different role in our application. The Electron runtime includes a number of different modules to assist you in building your application. Some modules—such as the ability to read and write from the system’s clipboard are available in both types of processes. Others, like the ability to access operating system’s APIs, are limited to the main process.


kinney_1_04

Figure 1.4. Electron’s multi-process architecture.


The main process

The main process has a few important responsibilities. It can respond to application lifecycle events like starting up, quitting, preparing to quit, going to be background, coming to the foreground, and more. The main process is also responsible forcommunicating with native operating system APIs. If we wanted to display a dialog to open or save a file, we would do it from the main process.

Renderer processes

The most important ability of the main process is that it can create and destroy renderer processes. Renderer processes can load web pages to display a graphical user interface. Each process takes advantage of Chromium’s multi-process architecture and runs on its own thread. These pages can then load in additional JavaScript files and execute code. Unlike normal web pages, we have access to all of the Node APIs in our renderer processes, allowing us to leverage native modules and lower level system interactions.

Renderer processes are isolated from each other and unable to access operating system integration APIs. Electron includes the ability to facilitate communication between processes in order to allow renderer process to communicate with the main process in the event that they need to trigger an open or save file dialog or access any other OS-level integration.


Electron vs. NW.js

Electron is similar to another project called NW.js (previously known as node-webkit). The two share a lot in common. In fact, zcbenz was a heavy contributor to NW.js before starting work on Electron. That said, they’re different in a number of important ways.


Table 1.1 A comparison of some of the main differences between Electron and NW.js.

Electron NW.JS
Platform Officially-supported Chromium Content Module from recent build Forked version of Chromium
Process Model Separate processes Shared Node process
Crash Reporting Built-in Not included
Auto-Updater Built-in Not Included
Windows Support Windows 7 and later Windows XP and later

NW.jsuses a forked version of Chromium. Electron uses Chromium and Node.js, but does not modify them. This makes it easier for Electron to keep pace with the most recent versions of Chromium and Node. Electron also includes modules for automatically downloading updates and reporting crashes. NW.js does not.

NW.js applications start from an HTML page. Each browser window shares a common Node process. If more than one window is opened, they all share the same Node process.Electron keeps the Node and browser processes separate. In Electron, we start a main process from Node. This main process can open browser windows. Each browser window is its own process and Electron provides APIs for facilitating communication between the main process and the browser windows—which we’ll call renderer processes throughout this book.

If backwards compatibility is a concern, then NW.js might be a better choice as it supports Windows XP and Vista. Electron only supports Windows 7 and later.

In summary, Electron allows developers to build a new class of application with their existing skills as a web developer.We looked at some of the integrations with the underlying operating system that Electron provides as well as some of privileges afforded to Electron applications that wouldn’t otherwise be available in the browser. It’s easy to get started with using Electron to build applications that would never be able to build in the browser.