Skip to content
CLOVERWRIGHT
← Back to blog
2 min read

Why we build native instead of Electron

macOSiOSEngineering

Every few months a founder asks us to "just wrap the web app" instead of building a native macOS client. It's a reasonable question — a webview ships faster, reuses the existing frontend team, and looks identical to the browser version on day one. We still say no more often than we say yes, and it's worth explaining why.

The cost shows up later, not on day one

An Electron app and a native Swift app can look nearly identical in a launch screenshot. The difference shows up six months in: memory usage under real workloads, cold-start time, how the app behaves when the Mac goes to sleep with a signing operation half-finished, whether VoiceOver actually works, whether the app respects system-wide settings like reduced motion or accent color. None of that is visible in a demo. All of it is visible to a user who has the app open eight hours a day.

For the categories we work in most — signing tools, monitoring utilities, anything that touches keys or credentials — there's a second cost that matters more: a webview process is a much larger attack surface than a native binary that never renders untrusted HTML. If the app is going to hold a private key or approve transactions, we want the smallest amount of code standing between the user and that key, not a full Chromium runtime.

Where a webview is the right call

We're not dogmatic about this. If the product is a dashboard that's genuinely the same information architecture on web and desktop, and there's no local hardware or secure-storage requirement, wrapping it can be the pragmatic choice — especially pre-product-market-fit, when the team's time is the scarcest resource. The mistake is treating that as the default rather than a deliberate tradeoff.

What "native" actually buys you

  • Secure Enclave and Keychain access without shelling out to a helper process.
  • Real system integration — menu bar presence, Services menu, Spotlight, Shortcuts, Handoff — the things that make an app feel like it belongs on the platform instead of visiting it.
  • Predictable performance on both a base MacBook Air and a Mac Studio, because you're not carrying a browser engine's baseline memory footprint into every window.
  • App Store distribution and notarization, which matters more than most teams expect once a security-conscious customer starts asking how the app is signed.

How we decide

Before we write a line of Swift, we ask three questions: does the app need to touch anything the OS considers sensitive (keychain, secure enclave, camera, file system beyond the sandbox)? Does it need to feel instant, every time, including cold start? And does the target user actually live in native apps, or are they arriving from a browser tab and just want the same thing in a window?

Two "yes" answers is usually enough to build native. One "yes," particularly the first one, is enough on its own.