Progressive Web Apps & Electron
It's 2019 and browser developers are excited about a new generation of websites: PWAs (short for Progressive Web App) are web applications supposed to bridge the gap between native applications and websites. You might be wondering: How does Electron fit into this story? Should I build an Electron app or a PWA?
What are Progressive Web Apps?
PWAs are built using a collection of technologies helping web applications present themselves as more natural citizens on user's devices. The term PWA doesn't describe a particular platform or technology but rather a set of attributes that PWAs typically have:
- Responsive: Fit any form factor, both on mobile and on desktop
- Offline-capable: Uses service workers and caching methods to retain functionality under degraded network conditions
- App-like experience: Present more like a native app than a website - with an icon on desktop or home screen, and their own window outside of the typical browser tab
At the core, these apps remain web applications. The client-side code is written in JavaScript or WebAssembly and they inherit their capabilities from the browser that's driving them. On the desktop, they are run by either Chrome, Edge, or Firefox. Take note of this point, as it'll come up again.
For more information about what PWAs actually are or how you build one, check out Google's PWA portal, Microsoft's portal, Alex Russel's first introduction of the term, or Aaron Gustafson's summary in A List Apart. To see some apps in action, check out Twitter Lite, the Financial Times App, or the often-mentioned Starbucks PWA.
What is Electron?
Electron is a platform for building cross-platform desktop applications with HTML, JavaScript, and native code. It does so by combining Chromium's rendering engine libchromiumcontent, Node.js, and a thick layer of native APIs for common native operations.
The more popular examples for Electron apps are Visual Studio Code, Slack (the one I work on), Twitch, Skype, or the installer for Visual Studio.
In a nutshell, developers can use Electron to build applications that contain Chrome's rendering engine while having access to all of Node.js - including every module available on npm.
Which one should I choose?
The big difference between Electron apps and PWAs is that the former is a full-blown native desktop application. It lives in user-space, together with apps like Notepad, iTunes, or Microsoft Office. Thanks to Node.js Native Addons, it can run C++ and Objective-C. There is no native API offered by the operating system that your Electron app cannot make use of. If Apple releases a new gimmick tomorrow (say, an upgraded Touch Bar or a fancier version of Handoff), your app can immediately make use of said technology. An Electron app lives in user mode and is the master of its own destiny.
In contrast, PWAs exist within the confines of the browser that power them. On Chrome OS or macOS, that's Chrome, on Windows, that's likely the Windows Store and Edge. If your app wants to make use of an API offered by the operating system, the browser vendor must first make those features available to PWAs. Some support is available (Edge exposes some WinRT APIs, for instance), but generally speaking, PWAs do not interact directly with WinAPI, AppKit, or any other technologies used by native desktop developers.
Let's look at a little chart displaying the capabilities available to a piece of software: The outer-most circle represents the operating system, which directly controls hardware and memory. The inner-most circle represents static websites, which don't run any code. PWAs are a bit more powerful than web apps. Electron apps are desktop software. Web apps can be a part of PWAs. PWAs can be a part of Electron apps. Electron apps usually contain a large amount of JavaScript and HTML, but nothing keeps Electron developers from writing native user interfaces and interactions.
With Great Power Comes A Cost
Before you walk away with a "Got it, Electron apps are more powerful than PWAs", hold up for a second: There's a real cost associated with that power. I've written a few Electron apps (windows95, Slack, Electron Fiddle) and can tell you about the things that excite me about PWAs:
- Installing and Updating: Automatically updating desktop software is extremely difficult. PWAs are, despite their offline-capabilities, still primarily websites. Service workers make caching your content easy. While PWA developers have no control over the installation process, they also don't need to worry about it.
- Security: Web developers live inside a golden sandbox - they are strictly controlled by the browser. While this dramatically restricts what your app is capable of, it also reduces security headaches. Electron apps that load and display remote content need to carefully consider how they keep said content in check.
- Size: A PWA is installed by simply visiting a website. An Electron app will likely never be smaller than 45 megabytes.
- Performance: Since PWAs are powered by the browser, they share resources with it. Since Electron brings its own rendering engine and Node.js, there's overhead that needs to be accounted for.
- Mobile: Electron is and will likely always be for building desktop software. PWAs are more flexible.
With Great Power Comes Power, Too
That said, there are a few things that really hold me back:
- Installing: As a user, installing a PWA is a multi-step process. If you have any customers running Windows 7, macOS, Linux, or earlier versions of Windows 10, prepare to support them in installing specific versions of browsers. That kind of matrix is an absolute no-go in most enterprise scenarios. Asking a customer to install your software is often a lot easier than asking them to install Chrome.
- Unclear Capabilites: When building a PWA, it's not entirely clear what capabilities your app will have. A PWA in the Windows Store has vastly different abilities than a PWA on Android, which has different abilities from a PWA in Chrome on macOS. If you go with the smallest common denominator, you won't be left with much beyond service workers.
- Native Capabilities: Running native code in Electron is a breeze. If I need to query whether or not
Do not disturb
is enabled on macOS, I don't worry about browser support - I write a few lines of Objective-C and break for lunch. - Offline, unless not: DevDocs is one of my favorite PWAs. Their offline docs recommend to open the page before going offline, just to make sure that everything is loaded. That sort of user uncertainty is a lot easier to avoid if your app is a binary on the user's machine.
Summary: For real, which one should I choose?
If you're building a web application, you should probably build a progressive web app. There are few reasons not do it - I've found Service Workers surprisingly easy to work with and a bit of offline capabilities will delight users.
Eventually, you might find that you bump against the edges of the browser's sandbox. There may just be some capabilites that justify the cost of maintaining a desktop application for you. Those demands can be straightforward - in Visual Studio Code's case, think of file system access, the terminal, or native debugging. In some scenarios, asking the user to first install a certain browser could be a difficult obstacle. In other cases, simply not being constrained by any browser is a worthy goal.
Browser Product Mangers sometimes ask me what kind of APIs PWAs need before Electron becomes unnecessary. The correct answer isn't a list of APIs, but a wildcard. Electron allows me to not make that decision. With an Electron app, there are no user-land scenarios my product managers can come up with that I won't be able to build.
In other words: If you're building an app with web technologies, make it a progressive web app. Once you've outgrown the constraints given to you, make your PWA run within Electron. Until you have needs that aren't met by progressive web apps, don't incur the cost of maintaining your own desktop software.
Photo by Ant Rozetsky on Unsplash