Every time you open a "modern" desktop app, you're quietly paying a RAM tax. Notepad on Windows 11? ~50 MB. The Win32 equivalent in pure C? 1.8 MB. That's not a rounding error β that's a 27x bloat multiplier for an app that moves text around.
At Gerus-lab, we build performance-critical products β from high-frequency trading UIs to real-time blockchain dashboards. We've had this exact fight internally: "just use Electron, it's faster to ship" vs. "our users will hate us at month three." This post is the result of that argument.
The Electron Bargain You Didn't Read
Electron's pitch is seductive: one codebase, web skills, ship to all platforms. And for many products β especially internal tools, dev tools, or apps where a second of startup latency doesn't matter β it's a completely reasonable trade.
But let's be honest about what you're actually shipping:
- A full Chromium instance (120β200 MB baseline RAM)
- A Node.js runtime
- Your actual app logic (probably 2β10 MB)
- A build artifact that's 80β150 MB on disk
VS Code takes ~300 MB of RAM on startup. Slack? Routinely 400β800 MB with a few workspaces open. Discord, Figma's desktop client, Notion β all Electron or Electron-adjacent. On a fresh Intel Ultra 9 285 with 32 GB RAM, one user reported Windows 11 sitting at 77% memory usage before doing any real work.
This isn't theoretical. It compounds.
What We Actually Lost
There was a golden era of Windows desktop software β roughly Windows 98 through XP β where apps had personality. Windows Media Player had a skin engine. Winamp was 640 KB and could play audio while Photoshop was running on 128 MB of RAM. Desktop pets wandered your screen. Media players looked like spaceship dashboards.
Those weren't just aesthetic flourishes. They were proof that developers had direct control over rendering pipelines. Win32's SetWindowRgn let you make a window literally any shape. UpdateLayeredWindow gave you per-pixel alpha compositing. A bitmap could simultaneously define what your app looked like and what shape it was.
Now? Most "desktop" apps are just browsers in a trench coat.
The Win32 Mental Model (And Why It Still Matters)
Here's what's interesting: Win32 isn't dead. It's just unfashionable.
The core pattern is message-driven, not loop-driven:
while (GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Your app isn't running a frame loop β it's responding to events that Windows delivers. WM_PAINT says "redraw yourself." WM_SIZE says "you've been resized." WM_DESTROY says "you're done."
This model has a learning curve that modern frameworks deliberately abstract away. But that abstraction has a price: you lose the ability to do things like this:
// Make the window literally oval
region = CreateEllipticRgn(0, 0, rc.right, rc.bottom);
SetWindowRgn(hwnd, region, TRUE);
Or drive window shape from a bitmap:
#define TRANSPARENT_COLOR RGB(255, 0, 255) // magenta = void
// Scan BMP pixels β build HRGN β SetWindowRgn
Or create a layered window with per-pixel alpha for animations that genuinely compose with the desktop.
None of this requires a framework. It's direct system calls.
The Performance Reality at Gerus-lab
We built the monitoring dashboard for a GameFi project (gerus-lab.com) that needed to display real-time on-chain events at sub-100ms latency. First prototype was Electron + React. It worked. It also consumed 340 MB of RAM and introduced 80β120ms of IPC overhead between the Node.js main process and the renderer for every price tick.
We rewrote the core rendering layer in C++ with Direct2D. Same data, same logic. RAM dropped to 45 MB. Latency dropped to under 10ms. The "it's faster to ship" argument aged poorly when we were spending two weeks profiling Chromium internals.
For SaaS dashboards and internal tools? Electron is fine. For anything where performance is a product feature, the bloat is a bug you chose to introduce.
The Tauri Compromise
If native Win32 feels too far back, Tauri is the most honest modern compromise. Instead of bundling Chromium, it uses the OS's native WebView (WebView2 on Windows, WKWebView on macOS). Typical binary sizes: 2β10 MB vs Electron's 80β150 MB. RAM usage is dramatically lower.
You still write your UI in web tech. You still have Rust (or JS) for the backend logic. But you're not shipping a second browser to run inside the first one.
We've started recommending Tauri over Electron for new client projects at Gerus-lab unless there's a specific Electron dependency. The developer experience gap has closed enough that the performance win is basically free.
When Electron Is Actually Fine
Let's not be dogmatic. Electron makes sense when:
- Your team's expertise is entirely web β the productivity gain is real
- The app is always competing for attention with a browser anyway β VS Code, for instance, is actually well-optimized for Electron
- Complex plugin ecosystems β Electron's Node.js integration makes extension APIs much simpler
- Cross-platform parity matters more than performance β and you've measured that it's good enough
The problem isn't Electron existing. The problem is reaching for it reflexively for every desktop app without measuring the cost.
What This Means for Your Next Project
Before you scaffold npx create-electron-app, ask:
- Does this need to be a desktop app? A PWA might be enough.
- How performance-sensitive is the critical path? If it processes a lot of data in the background, native will matter.
- What's the long-term RAM budget? Users with 8 GB machines who run 15 apps notice.
- Can you isolate the heavy logic from the UI layer? Even in Electron, moving CPU work to a native addon helps.
At Gerus-lab, our default for new products is: web-first β Tauri if it needs to be native β C++/Rust if performance is a core feature. Electron lives in a specific middle tier, not at the top of the stack.
The Win32 Project Worth Exploring
If you want to see how far native Windows programming can still go, there's a GitHub repository floating around right now (the source of the Habr discussion that inspired this post) showing oval windows, bitmap-shaped windows, and animated desktop pets β all in pure Win32 C with no framework dependency.
It's not a production recommendation. It's a reminder of what "full control" actually looks like, and why some developers miss it.
Bottom Line
The RAM bill for Electron apps is real, it compounds across your users' machines, and it's a choice you're making β not an inevitability of desktop development. Native isn't dead. It's just waiting for someone to decide the performance is worth it.
We've made that call several times at Gerus-lab. Sometimes web wins. Sometimes native wins. But we always measure.
Building something performance-critical where the tech stack decision actually matters? We've made these calls in production β gerus-lab.com













