HyperDisk icon

Too many Mac apps are being built with Electron

Electron /ɪˈlɛktrɒn/ n. 1. An application development framework for building cross-platform desktop apps using web development technologies such as JavaScript and CSS.

The quest for cross-platform development

For years, people have been trying to shortcut cross-platform development. Back in the 90s, Steve Jobs’ NeXT had evolved NeXTStep into OpenStep, a forward-thinking but ultimately unsuccessful platform that allowed you to use NeXT’s beautiful Objective-C language to make Windows apps. (Fun fact: John Carmack used a NeXT to write the original DOOM game.)

In more recent times Microsoft released Xamarin. Similar in concept to OpenStep, it broadens the base of Windows programmers by letting them deploy their apps across platforms.

And now after a couple decades, cross-platfrom development is finally catching on and going mainstream. It’s doing so with web-influenced tools like React Native and Electron. Users are not better off because of it.

NeXT’s OpenStep was a pioneer for cross-platform development. It became the backbone of Mac programming after Apple bought NeXT.

External frameworks add bloat.

The more external frameworks an app uses, the less native it becomes. Full app development frameworks like Electron or React Native basically supersede the native app building toolbox with their own thing. Building an app with one of these frameworks means you have a single code base for multiple platforms, but your app is neither a native Windows app nor a native Mac app. It’s something else entirely: an Electron app, which is a lot like a web app. We all know how browser-based web apps tend to feel. Things lag, they’re inconsistent, you’re never sure whether stuff like copy & paste or drag & drop is going to work, you’re not sure where (or if) your work is getting saved, the list goes on.

Electron apps improve upon browser apps ever-so-slightly, by running web code within a platform-specific runtime that has some closer integration with OS features like windows, buttons, copy & paste, etc. Also, they let you put an icon in your dock just like a regular Mac app. But at their core, they’re little different from a browser-based application, and this is something the user can feel.

How to find bloated apps

If you’re wondering how to tell which apps on your Mac are efficient and which ones are bloated, the quickest way is to look at how big the app is. This is as simple as clicking the app in the Finder and doing Command-I (get info.) An app that’s under 20MB is very lean. Apps over 100MB better have a good reason for being so big, and apps above 500MB are probably bloated, unless they’re games or legitimate mega-apps like Photoshop or Final Cut Pro.

Finding out what frameworks an app uses

One cool thing about macOS is that all applications are actually folders. You can open them up and see what’s inside. It’s a lot like popping the hood on a car.

Select an app in the Finder and right-click (or control-click) on it. Choose “Show Package Contents.” You’re now looking inside the contents of that Application. Click on Contents, and you should see the top level of the app bundle, with folders called MacOS and Resources. If there’s a folder here called Frameworks, then the app includes external frameworks. Click the Frameworks folder and you’ll see the ones the app uses. If you see Electron in there, then you’ve got an Electron app.

The frameworks inside an app are folders themselves. You can click them and do command-I to see how large they are. Some frameworks are pretty lean, and help with a small task (i.e. Sparkle, which many Mac developers use for app version updates.) Some are enormous, and include an entire application runtime within themselves.

The Electron framework can be about 200 MB in size. That's 7 times the size of Graphic.app, a good full-featured illustration app. That’s nuts.

Get Info
Get Info will give you a quick idea of how bloated an app might be.

A tale of two apps: BBEdit and WhatsApp.

There are a few apps that I usually have running on my Mac. Safari, Xcode, iTerm, Mail, WhatsApp, BBEdit. Let’s pick two apps and use them as our poster children. BBEdit can be the poster child for a cleanly written Mac app, and WhatsApp can be the poster child for janky Electron bloatware.

Before I start digging into the apps, let’s think about what the apps actually do. BBEdit is a text & code editor with syntax support for about 50 programming languages, full regex search & replace, an SFTP/FTP browser, HTML templates, code folding, minimap, and a huge list of other features. WhatsApp is a messenger app. It lets you send text, pics and audio to your friends. That's it.

With that feature list you’d think BBEdit would be the bigger of these two, but it’s actually the opposite. BBEdit weighs in at a respectable 65MB. WhatsApp lands with a dull thud at just over 324MB.

Yes, that’s 324MB of disk space… for a texting app. It’s nearly 100x the size of Apple’s Messages app, which does basically the same thing as WhatsApp. We programmers have got to stop building stuff this way.

BBEdit and WhatsApp
Two Mac apps, built very differently.

Application bloat does more than just take up space.

Apps live on your disk, so they take up disk space whether they’re running or not. While they’re running they also take up RAM (memory,) and use CPU processing power. These things all make your Mac “run hot,” both figuratively and literally. These unnecessary power draws will affect overall system performance, waste energy, and reduce battery life.

Test 1: Launch time

This test gets into the concept of “feel,” as in the way an app feels when you run it. Efficiently written apps feel as if there’s nothing standing between you and the computer, no gunky layer to gum up the works and slow things down.

Bloated or badly-programmed apps often suffer from poor launch times. In this test, there’s no contest between BBEdit’s 1 second launch time and WhatsApp’s 16 seconds on a 2021 MacBook Pro.

Test 2: Memory

It’s a common mistake to conflate “memory” and “disk space,” but they're different things. Memory is RAM—it has to do with how much stuff you can run at once. Disk space has to do with how much stuff you can store on your computer.

BBEdit, while open in a typical working scenario, is using 173 MB of memory. That’s no small potatoes, but it’s a pretty small chunk of the 8-32 GB that’s installed on most Macs today.

WhatsApp, on the other hand, is using 110 MB. Wait, what? That’s less than BBEdit... that blows up my whole... oh wait. Never mind, WhatsApp is running 5 weird “helper processes” and using about 1.4 GB in total. That’s actually worse than I expected.

Let’s take a step back once again, and process the fact that a texting app is consuming Photoshop-league memory, just to display your text messages. This is Electron Apps, and they must be stopped.

And while we’re at it, let’s talk about those helper processes. Their names are WhatsApp Helper, WhatsApp Helper, WhatsApp Helper (GPU), WhatsApp Helper (Renderer) and WhatsApp Helper (Renderer). A Mac app shouldn't need any of these. They’re probably communicating with each other using sockets or ports, or maybe shared files. This really isn’t how you’re supposed to build a Mac app. This shouldn’t become normalized. As Scotty said in Star Trek III, “the more they overthink the plumbing, the easier it is to stop up the drain.”

Launch time
Launch times for BBEdit and WhatsApp for Mac. Measured as time between clicking the icon and the app being usable.

Test 3: CPU

The CPU is the brains of the computer. An app is a good citizen if it uses the CPU sparingly. This means more CPU power is available to other processes, power consumption is reduced, and (on a laptop or phone) battery life is extended.

As a rule of thumb, apps should use little or no CPU when they’re not doing anything. This is a core concept of event-driven programming, and it’s been the proper way of doing things for decades. Apps that use CPU when idle are probably doing some form of polling, where they constantly check something over and over instead of waiting to be notified when events happen. Games can get away with this, but productivity apps shouldn’t.

First I tested BBEdit. When in the background and not doing anything, it used between 0.0 and 0.1 percent CPU. This appears to be close to the minimum for a running Mac app.

Next, I looked at WhatsApp. Between the main app and two of its helper processes, it was usually running at 10-15% CPU usage, while in the background. I tried to delve into what exactly is causing all that CPU usage, so I ran sample <pid> in the terminal to see what WhatsApp was doing. I found a bunch of activity within the Electron framework, with function names like: v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*). Unfortunately all this really tells me is that I’m looking at “Electron stuff”.

CPU activity
Comparing BBEdit and WhatsApp’s CPU usage in Activity Monitor

Test 4: GPU

I wasn’t expecting to test GPU usage until I looked in Activity Monitor and noticed heavy GPU usage for no apparent reason. Well the culprit was WhatsApp, who apparently uses the power-hungry GPU in the background. To be fair, this one might not be Electron’s fault. The usage is coming from the WhatsApp Helper (GPU) process which seems to be an “Electron Thing,” but I tested a different Electron app (Cursor) and found that its GPU helper process isn't using the GPU so heavily. So this one may be due to bad WhatsApp code rather than Electron… or feasibly a combination of the two.

Oh, and BBEdit uses 0% GPU when it’s in the background, which is normal and expected.

GPU activity
Activity Monitor’s GPU History shows the difference in GPU usage before and after quitting WhatsApp.

Let’s get back to lean, clean Mac apps.

Apple puts a lot of work into making a complete, polished development environment. The best Mac apps are the ones that use Apple’s own tools and toolkits, and stick closely to them… apps like BBEdit️⌨️, Transmit🚚, iTerm🤓, Gifski🎬, Pixelmator🎨, HyperDisk️❤️. Not apps that link in a lot of big bloated frameworks like WhatsApp🏢, Zoom🏢, Slack🏢, Discord🏢. (For some reason this category of app just loves huge frameworks.)

There are surely times where frameworks make sense. If you’re doing a big high-end 3D game, then Unreal Engine is probably the right way to go, and it’s as heavy as frameworks get. Or if you’re doing a Mac app, you can still keep it clean by linking to one or two lightweight single-purpose frameworks like Sparkle (though zero is always coolest).

The Electron trend seems to be picking up steam. In my years I’ve seen bad trends come and go, and I hope this one ends up being a short-lived fad and not a new normal.

no AI
This blog might not win a Pulitzer Prize, but at least it’s real.
Everything on HyperDisk’s website was written by a human.