← All posts

2026-04-14

Native App vs Electron and PWA: A Mac Dev's Take

swiftswiftuimacoselectronpwanative

Native App vs Electron and PWA

I've spent the last year building hora Calendar as a native Swift/SwiftUI app for macOS and iOS. Before I started, I had the same argument with myself that everyone has: just ship Electron and be done. It's faster. It's cross-platform. The hiring market is ten times bigger.

I didn't, and I want to write down why — because most of what's online about native app vs Electron is either an agency post selling you cross-platform work or a one-line "Electron is bloated" dunk. Neither is useful when you're actually deciding.

So here's the four-way comparison from someone who picked native and shipped it: native, Electron, PWA. (Web wrappers I'm folding into PWA — a wrapped webview is a PWA wearing a hat.)

What you're actually choosing between

These three things get compared like they're interchangeable. They're not.

Native means writing against the OS directly — Swift/SwiftUI on Apple platforms, Kotlin on Android, C#/WinUI or Rust on Windows. You get every API the OS exposes. You also get to build everything twice if you want to be on more than one platform.

Electron ships your app as a packaged Chromium browser plus a Node.js runtime. Slack, Discord, VS Code, 1Password, Notion — all Electron. The app is a website, the website is the app, and the runtime is ~150MB on disk before you write a line of your own code.

PWA (Progressive Web App) is the website you already have, with a service worker, a manifest, and an "install" button in the browser. It runs in the OS's webview, not its own bundled Chromium. Lighter than Electron, more constrained than native.

If the question is "native app vs Electron, which one" — the honest answer is "what kind of product are you building, and how much does it need to know about the OS it lives on?" Below is what I learned by picking native for a calendar.

Memory and battery: the part nobody warned me about

The numbers people throw around are real. A native macOS menu bar app idles at around 15MB of RAM. The same app in Electron starts at 80–150MB before you've done anything, because you're shipping a full Chromium process and Node alongside your code.

That sounds like an abstract complaint until you have eight Electron apps open — Slack, Discord, Notion, Linear, Spotify, VS Code, 1Password, ChatGPT — and your M-series Mac is sitting at 6GB of RAM spent on Chromium instances that don't talk to each other. You wouldn't open eight Chrome windows and call it normal, but that's effectively what's running.

The most embarrassing recent receipt: in November 2025, Electron apps started causing a system-wide stutter on macOS Tahoe — window dragging and scrolling lagged across the whole OS, even apps that weren't Electron. The cause was Electron using a private AppKit API in an undocumented way. Apple shipped a fix in a Tahoe beta. But for weeks, every Electron user on Tahoe paid for it.

A native app can't cause that class of bug, because it doesn't need to reach for private APIs to render its own UI.

RAM: an Electron stack vs a native Swift app

The "feel" you can't fake with CSS

This one matters more than memory and is harder to measure. A Mac user can clock an Electron app in two seconds. They can't always tell you why — but they know.

Here's a partial list of what they're noticing:

When I'm comparing Swift vs Electron for a Mac app, this is the gap that closes the case. A calendar is something you open dozens of times a day. Every interaction either feels like the OS or feels like a tab pretending to be the OS. There is no third option.

(If you want a counter-argument from inside the Electron team, Felix Rieseberg's "Things people get wrong about Electron" is the fairest version. He's right about a lot of it. He'd also be the first to tell you a Mac-only app should probably be native.)

PWAs: closer to native than Electron, but…

PWAs are the under-talked-about middle option. You ship one website. The user "installs" it from the browser. It gets a Dock icon, runs in its own window, can work offline. It uses the system webview instead of bundling its own — so it's a fraction of the size and weight of Electron.

Basecamp moved their HEY desktop apps from Electron to a PWA wrapper and the numbers got dramatically better. For a doc-shaped, server-driven product, a PWA is often the right call.

Where it falls apart is when your app needs to be part of the OS, not run on top of it. The list of things hora needs that a PWA can't do, on macOS today:

For a thing that lives in the OS — a calendar, a launcher, a clipboard manager, a window tiler — a PWA can't reach far enough. For a thing that lives in a tab — a doc editor, a CRM, a dashboard — it's almost always the right answer.

hora widgets across iOS Lock Screen, iOS Home Screen, and the Mac desktop

What native costs you (the honest part)

I'm not going to pretend native is free. The trade is real:

For hora the math worked because (a) the audience is Apple users, (b) the product is the OS integration, and (c) I'd rather be slow and right than fast and forgettable. For a B2B SaaS dashboard, the same math gives you Electron or a PWA, easily.

When each one is the right call

The short version, after a year of living with the choice:

Decision matrix: pick Native for OS-integrated apps; Electron and PWA only for cross-platform team apps and server-driven tools

If you can't tell which bucket you're in, you're probably in the Electron or PWA bucket. Native is a deliberate choice with deliberate costs. Make it on purpose.

FAQ

Why are Electron apps so slow on Mac? Each Electron app is a full Chromium browser plus a Node.js runtime — they don't share resources with each other or with Safari/Chrome. Eight Electron apps means eight Chromium instances. On top of that, the November 2025 Tahoe lag bug showed Electron's reliance on private AppKit APIs can cause OS-wide stutter, not just slowness in the app itself.

Is Swift harder than Electron? Yes, if you're coming from web. Swift, SwiftUI, and the Apple frameworks are a different mental model — view trees, property wrappers, structured concurrency, EventKit, App Intents. The learning curve is steeper, but the surface area for one platform is finite. The Electron learning curve is shallower and the long tail (signing, notarization, auto-update, Chromium quirks) is forever.

Can a PWA replace a native macOS app? For document-shaped, server-driven apps — often yes, and increasingly yes as Apple exposes more web APIs. For apps that need EventKit, widgets, menu bar extras, App Intents, or background work the browser doesn't allow — no, not today and probably not soon.

If native is so much better, why does Slack use Electron? Because Slack runs on Mac, Windows, and Linux, ships from the same codebase as their web app, and a chat client doesn't need deep OS integration to do its job. Electron is the right answer for Slack. It's not the right answer for a calendar.


If you want to see what the native trade-off looks like in shipped form, hora Calendar is the receipt — Mac and iPhone, with widgets, menu bar, Focus filters, and the rest of the iceberg you can only build below the waterline. Roadmap and newsletter on the landing page.

Follow the build at @moto_szama, check out hora Calendar, or reach out at hello@horacal.app.

Stay in the loop

Get notified when hora launches. No spam.

or follow along
@moto_szama Star on GitHub