What's new

Desktop Apps Keep Getting Heavier

S

Shreyam Adhikari

Guest
Every app has a good reason to be heavy. Unfortunately, they all live on the same computer.

Your app is important. So are the other nine.

That is the part I keep coming back to whenever someone explains why their desktop app needs quite so much computer.

Open Cursor or VS Code. Discord for one group, WhatsApp for another. A database client. A music player. The actual browser, which also has work to do. None of this feels like an unreasonable way to use a computer.

Yet every app arrives with its own perfectly reasonable explanation for why it needs a little more memory, a few more processes, another background service. Taken one at a time, the argument often makes sense.

I don’t use them one at a time.

Electron makes a very good case for itself.​


I understand the appeal. You get the web’s UI tooling and libraries, a browser engine you can ship with the app, Node, and APIs for the desktop bits. And yes, you can make a great interface this way. Good typography, responsive controls, a rich editor, animations that don’t get in the way.

The web has an enormous amount of useful work already done. I like using it. Getting all of that into a small desktop app is the part that keeps becoming a problem.

From a company’s point of view, the trade can be worth it. If users spend their working day inside your product, perhaps they will happily give it the memory. Your team can improve one interface across operating systems instead of maintaining several separate versions.

But every company gets to tell itself that story. The user gets all of the apps.

I can believe your app deserves its resources and still dislike what happens when everyone makes the same argument.

For a tiny utility, Electron is off my shortlist. I want the tool to have a small footprint because its job is small. I also know that crossing Electron off doesn’t produce an obvious winner.

A smaller download. Still a web engine.​


The next idea sounds right: use the system’s web engine. Wails gives me a Go backend and a web frontend. Tauri does the related job with Rust. Electrobun also offers system WebViews, with optional CEF when you want to bring Chromium along.

That is useful. It is also where the word “lightweight” needs a little care.

On Windows, WebView2 still runs Chromium. On macOS, the usual system-WebView path is WKWebView; on Linux, Tauri uses WebKitGTK. Those last two are WebKit-based. Different engines, same underlying point: a web interface still needs a web engine to run it.

And the engine has processes of its own. Microsoft’s WebView2 process model includes a browser process, renderers, and helpers such as GPU and audio processes. A small number beside the host executable doesn’t describe all of that.

Task Manager isn’t faking the number. I might just be reading one row and treating it as the whole app. Equally, I shouldn’t add every WebView2 process on the machine to one app’s bill. Other programs use it too.

The smaller installer is real. So is the engine running somewhere else in the process list.

Look at the whole process group.​


Open the app, do some normal work, and let startup settle. These commands list processes, their parent IDs, and resident memory. Find your app’s PID, then follow the parent IDs to its helpers.

Windows — PowerShell, working set in MiB:

Code:
Get-CimInstance Win32_Process | Select-Object ProcessId,ParentProcessId,Name,@{Name='WorkingSetMiB';Expression={[math]::Round($_.WorkingSetSize / 1MB,1)}} | Sort-Object WorkingSetMiB -Descending

macOS — Terminal, RSS in KiB:

Code:
ps -axo pid,ppid,rss,comm

Linux — Terminal, RSS in KiB, with a process tree:

Code:
ps -eo pid,ppid,rss,comm --forest

These are snapshots, not an exact bill for the app. Resident memory can include shared pages, so blindly adding the rows can count the same memory twice. Parent IDs are a starting point; shared services and reparented helpers need more care. On Linux, PSS in /proc/PID/smaps_rollup apportions shared pages. On macOS, Activity Monitor’s Memory Pressure also tells you something a single process row cannot.

Compare the same workload and metric each time. A Rust or Go host can do unnecessary work too. Measure the product before declaring a winner.

Flutter gets a lot right. I still want less.​


I enjoyed working with Flutter. Building the interface felt good. Having a consistent set of widgets and a coherent way to put them together matters more than a framework comparison table can show.

Flutter brings its own engine and rendering stack. That makes sense for a substantial application. For the very small tools I have in mind, it still feels like more machinery than I want to bring along. That is a fit judgment, not a claim that every Flutter app is slow.

This is the annoying middle. The web has the tooling and the libraries. Flutter has a convincing UI story. I just want something small, efficient, pleasant to build, and comfortable to use. Apparently that is a longer requirements document than it sounds.

I love native. The path there feels broken.​


Native has always been where I want to go for small, efficient tools. Open quickly. Use the machine sensibly. Behave like the other software around you. A menu that feels right is a small pleasure, but I notice it.

I tried Avalonia and .NET MAUI too. Neither became the easy answer I was looking for. Go further toward each platform’s own toolkit and the integration can be lovely. Then you need another operating system. Different controls, different text behavior, different menus, different packaging. Qt is a real option here, and C++ isn’t compulsory: it officially supports Python too, with QML available for the UI. For me, that still means another UI ecosystem to learn.

I know these operating systems are different. I know a perfect abstraction might never exist. That doesn’t make the current experience feel good. This is a rant, after all.

Consistency brings Electron back.​


A product team usually wants its product to feel like its product on every OS. The same editor. The same layout. The same release arriving with the same features.

A bundled browser narrows the rendering differences. It doesn’t erase OS bugs, but it gives the team a more controlled target. Add familiar tools, a huge pool of web libraries, debugging people already know, and years of work on packaging and updates. Electron starts looking sensible again.

So when a company chooses it, I don’t assume they forgot native apps exist. They may be buying practical assurances that the alternatives haven’t matched for their product.

I can understand that decision and still be tired of paying for it across my entire desktop.

The missing desktop piece.​


I want a good-looking interface without a large runtime budget becoming the entry fee. I want the libraries and tooling I enjoy without the feeling that a small utility has quietly turned into a browser distribution project.

I don’t have a solution to reveal at the bottom of this post. No framework wins the last paragraph. We have good tools, awkward trade-offs, and a gap that still feels much larger than it should.

Your app may be my most important app.

It still has to share my computer.

Adapted from my original essay, which includes the fuller technical references.
 

Thread statistics

Created
Shreyam Adhikari,
Replies
0
Views
2
Back
Top