Skip to content

The stack won’t make your app native

14 minutes

Native apps seem to be having a bit of a moment. In February, Drew Breunig asked why Claude’s desktop app was built with Electron (opens in a new tab), when coding agents could now ship native code to every platform. In June, at WWDC, Apple revealed that Notion was moving to SwiftUI (opens in a new tab). Then in September, Shopify announced they were leaving React Native behind for Swift and Kotlin (opens in a new tab), because “LLMs changed one of the core assumptions behind our 2020 decision”.

It’s not only big names like Shopify going native, either. The same day they announced it, the small team behind mymind shipped their new iPhone app (opens in a new tab), “now fully native”, and a couple of weeks later, even Vercel’s Guillermo Rauch — about as big a champion of the web as there is — rebuilt his mini browser in Rust and Swift (opens in a new tab), then declared:

Native is the future, both on the desktop and in the cloud.
Guillermo Rauch

For anyone who cares about the Mac, that’s good news. The Mac has been a part of my life since long before I started writing code for a living, and over the years, it’s become the computer I trust for everything, largely because of Apple’s consistent and considered philosophy towards both their hardware and their software. Today, a lot of the apps I depend on no longer share that philosophy, so this is a shift I’d quietly been hoping for. If AI really has made it cheap to build an app properly for any platform, the main argument for doing anything else has now dissolved.

The real question is: which native are we about to get?

Two meanings

When most people say “native”, they mean “not Electron”. The app is written in Swift, Rust, or something else that runs straight on the machine instead of inside a browser engine. That is a very real difference. Native code is faster, lighter, and plays better with everything else on your system.

But that isn’t, in my experience, what people who care about Mac apps mean when they say “native”. We mean an app that belongs on the Mac, and those are two different things: one is about what an app is made of, whilst the other is about how it feels to use.

There’s actually a term for this second kind of native:

Mac-assed Mac app/ˈmak ast mak ap/noun
An app that’s unapologetically Mac: it uses the system’s menus, settings, and conventions, and behaves the way the rest of your Mac has taught you to expect.
Coined by Collin Donnell, popularised by Brent Simmons in 2020

Simmons used it in March 2020 (opens in a new tab) to praise Proxyman, a tool for inspecting network traffic, as the kind of app that’s made for one platform and isn’t “trying to wow us with all their custom not-Mac-like UI”. He counted his own NetNewsWire as one too, and called that “a point of pride”. The next day, John Gruber weighed in (opens in a new tab), saying he loved it because it was clearer than just saying “native”. His reason was the same as mine for writing this:

Native is ambiguous.
John Gruber

He noted that you could even argue Slack was native (can you imagine?), since back then, anything you didn’t use in a browser counted. But as he put it, it “sure as shit” wasn’t a Mac-assed Mac app.

To be clear, native isn’t a concept exclusive to the Mac. You can build natively for Windows, Linux, or Android, and the same split applies. But say “native”, and I’d wager it’s the Mac most people picture. Apple claims to take software as seriously as hardware (Steve Jobs once said (opens in a new tab) that Apple “views itself as a software company”), and they build the two to work as one; that’s why people buy a Mac. It was true when the Mac was a niche, and it’s still true now that it isn’t. So Mac users have come to expect the same of every app they install, and it’s on the Mac that the gap between the two kinds of native is easiest to see.

What it looks like in practice

I’ve always noticed this gap most in code editors, because I’ve practically lived in them since I was a student. My first was Macromedia Dreamweaver (yes, Macromedia). I stuck with it through Adobe’s Creative Suite until I found Panic’s Coda (opens in a new tab). That changed the game. It was the first time I can remember choosing a piece of software for how it felt rather than just what it did. From then on, I was hooked, and I went looking for that feeling in every app I tried. Apps like Espresso, CodeRunner, and a handful of others had it too. They were Mac-assed before anyone called them that.

As the web got more complicated, though, so did what I needed from an editor, and like most people, I went wherever everyone else was going. First to Brackets, which was really a web page running in a Chromium shell (opens in a new tab). Then Atom, the editor Electron was originally built for (opens in a new tab). Then VS Code, built on Electron too. Each one felt a little less at home than the last, and the longer I lived with VS Code, the more I resented it, until I became desperate to move on. Soon after, Panic finally shipped Nova (opens in a new tab), the successor Coda users had been waiting years for, and it felt like coming home. I stayed for a long time, until I found a new editor in Zed.

By any technical measure, Zed is native. It’s written in Rust and draws its whole interface on the GPU (opens in a new tab) with its own framework, and it’s the fastest modern editor I’ve ever used. It also looks great. But almost nothing about it belongs on the Mac. The context menus, the sidebars, the settings — all of it is its own. Nova is the opposite: almost everything about it belongs, from the system’s own context menus and sidebars to a settings window like any other Mac app’s. It was held up as proof that Mac-like design matters (opens in a new tab) when it came out.

Both are native, yet only one of them feels like it.

You can see the difference everywhere once you start looking. Ghostty, a terminal app, makes the clearest comparison with Zed. Its core is written in Zig, a low-level language like Rust, but rather than drawing its own interface, it builds the Mac app with Swift and AppKit. Its documentation (opens in a new tab) even spells out what it means by native:

Designed to look, feel, and behave like you expect an application to behave in your desktop environment.
Ghostty’s documentation

Mimestream, a Gmail client, was built by an engineer who spent seven years working on Apple Mail, and it shows. It’s written in Swift, but what people praise is how much it feels like a real Mac app (opens in a new tab).

Some of the apps that do this best are utilities. When I went looking for a dictation app, Wispr Flow felt like opening a web page and used far more memory than something that simple should, so I downloaded every reasonable alternative I could find and had Claude sift through their app bundles to see what each one was built with. Electron, Electron, Tauri, Electron, Tauri… For something that runs in the background all day, any of those is a one-way ticket to my bin. That still left plenty of native ones, but being native only got them on the list. From there, it came down to which one was the better product, and for me, that was Superwhisper. The good ones are made by people who sweat the details of something you might only look at for a few seconds a day, and make it every bit as capable as it is polished.

The tools you live in

Where it gets harder is with the big tools: the kind you spend all day in, where every panel, menu, and shortcut is another chance to get it wrong.

Craft, which I use for my own writing and admin, turns the stack argument on its head. The Mac app is built with Mac Catalyst (opens in a new tab), from the same codebase as the iPhone and iPad apps, and the team builds nearly all of their own components rather than using Apple’s. That’s the same choice Zed made, so you’d expect it to feel just as out of place. Yet where Zed’s parts feel like Zed’s, Craft’s feel like the Mac’s. Even Apple seems to think so: it named Craft Mac App of the Year (opens in a new tab) in 2021, and engineers at Apple asked the team (opens in a new tab) how they managed an animation that Apple’s own navigation bar on the iPhone couldn’t do.

For me, the difference is clearest next to something like Notion (nothing personal, Notion team). Craft and Notion do much the same job, and between work and everything else, I’m in both almost every day, so it’s an easy comparison. What bothers me most about Notion is that it just doesn’t behave the way the rest of my system has taught me to expect, which is exactly the point Simmons and Ghostty were making. Underneath, it’s a website, and you can see it wherever you look. Drag the window narrower and everything inside it lags and stutters as it reflows, like a poorly built web page. Every time you open the app, you get a flurry of spinners and empty placeholders whilst it pieces itself together. Sections slide open and shut with a motion borrowed from the browser, nothing like what you’d see in Finder or Mail. Look in the menu bar and you’ll even find Toggle Developer Tools, which opens Chromium’s inspector on the app itself. In a real Mac app, stuff like that can’t and shouldn’t exist. Notion’s far from the only offender. Slack, VS Code, and plenty of other apps built on the web show the same symptoms, each in its own way.

Craft has none of that. I don’t want to dismiss the effort Notion’s team puts in, but they’re building for the web first in a bid to be everything to everyone, whereas Craft’s team treats each platform as its own. Rather than stretching one app across all of them, they’ve taken their time with each one, spending three years on Windows (opens in a new tab) and only reaching Android (opens in a new tab) (in beta) last year. Waiting can be frustrating as a user, but I think it’s worth it, because every platform deserves its own attention (the web included).

So if it’s not the stack or Apple’s own parts, what is it?

Fluent in the Mac

Sketch is the closest thing I have to an answer. Back in 2020, the team published “Part of your world (opens in a new tab)”, their case for going truly native, and it’s still one of my favourite things anyone’s written on the subject. It’s also still the app that feels most at home on my Mac. Whenever Apple redesigns macOS, Sketch changes with it, and everything from the toolbar to the settings looks like something Apple could have built themselves. Except, since last year’s redesign, a lot of it isn’t. Sketch swapped many of Apple’s components for its own (opens in a new tab), and Pieter Omvlee, one of its founders, was candid about why on Mastodon (opens in a new tab):

We shouldn’t have had to go this far in the first place if the design language actually supported what we can call ‘Pro Apps’. I mean Xcode looks like a toy now, that can’t be right surely.
Pieter Omvlee

That means the app that feels most at home on my Mac is now, in large part, built from parts Apple never made. Still, the team knows the Mac so well that the parts they build feel like they were always there. They’re fluent in the Mac: the pieces sit where you’d expect, behave how you’d expect, and fit in next to everything else. Zed’s, by contrast, speak their own language, however well they speak it.

It also shows that doing what Apple does isn’t always the answer, because Apple’s own choices are seemingly up for debate. Sketch kept Liquid Glass, but they felt Apple’s new design language wasn’t made with apps like theirs in mind, so they built what it was missing. Even Apple doesn’t always follow their own guidance: their Human Interface Guidelines (opens in a new tab) say to use icons in menus “sparingly and with purpose”, yet macOS Tahoe added one to nearly every menu item, as Nikita Prokopov picked apart in detail (opens in a new tab). Thankfully, a year later, macOS Golden Gate (opens in a new tab) fixed a lot of these quirks, taking most of those icons away again, making window corners consistent, and answering complaints about legibility with a slider that makes Liquid Glass more opaque. Evidently, following Apple to the letter isn’t the same as belonging, especially when Apple is still working things out themselves.

What native actually means

So here’s what I think “native” really means. Every platform teaches the people who use it how things should work: where the settings live, what a shortcut will do, how a window behaves. A native app respects that. It’s made by people who know those lessons well enough to follow them, to fill the gaps where the platform occasionally falls short, and to keep up as it changes, usually because they live there too. Somebody thought about what the menus should say and which shortcuts should work. Somebody made the settings feel like settings, and the window feel like a window. And none of it was traded away so the same app could run everywhere else. Focus over reach.

You only notice how much the platform taught you when an app ignores it and makes you learn its own way instead. For one app, that’s no big deal. But most of us don’t use one. We use many, switching between them all day, and that’s where the little differences add up. The web is an incredible platform, and it’s how I found myself doing what I do. It feels limitless. But that freedom means every web app does things in its own way. Tooltips appear instantly in one app and not at all in the next. Move your cursor diagonally towards a submenu and one app keeps it open whilst another snaps it shut. A shortcut works in one app and does nothing (or something unexpected) in the next.

Not all of it is deliberate, either. When an app brings its own foundations instead of using the Mac’s, it has to simulate the Mac, and every piece it simulates is another chance to miss something. A good example of this is window tiling. The Mac puts its own options for arranging windows in each app’s Window menu, but plenty of Electron apps build their own menu called Window that the Mac doesn’t treat as the real thing, because of a setting left out when the menu was declared. That single misconfiguration is enough to cut the app’s windows off from how the rest of the system handles windows: its tiling options are missing from the menu, and when you tile one with a shortcut, it jumps into place rather than gliding and reflowing smoothly. Zed is a native app with its own framework, so it has to simulate the Mac as well. It never set an app category, so Finder, Screen Time, and Spotlight filed it under Other until I fixed it myself (opens in a new tab) in October. Every one of these is something each team has to get right, and another way for apps to drift apart. None of it matters much alone, but when every app plays by its own rules, your Mac stops feeling like a cohesive system, and you can’t quite trust any app to behave the way you expect.

You feel the care (or the lack of it) long before you can put it into words. It’s why so much perfectly functional software still feels like something you put up with.

Putting up with it

Sometimes putting up with it is a trade worth making. For me, that’s Zed. The kind of native it is keeps me there: it’s fast and gets everything right for me. The kind of native it isn’t is all on the surface, and after hours (and hours) in it every day, that’s easy to forgive. I do notice it, though, and I’m not the only one. CodeEdit (opens in a new tab) is an open-source editor being built by its community with the Mac in mind from the very start. It’s still early (who knows where it’ll be once it’s finished), but people wanted a Mac-assed editor badly enough to start building one themselves. What I’m less sure of is how an app like Zed would get there. If Sketch is right about what Apple’s parts are missing, it would have to build its own, and if it did that half as well as Sketch, I’d have no complaints at all.

When the stack is cheap

Writing about Claude’s Mac app in August, Gruber said he’d rather use (opens in a new tab) a well-designed Electron app than a straight port to Swift of the same design, because:

The design itself is non-native.
John Gruber

I think he’s right.

If agents can churn out Swift or Kotlin as easily as TypeScript, the stack stops setting anyone apart. Plenty of apps will go native over the next year or two, as Rauch predicted. That alone is worth celebrating, whichever kind of native they turn out to be. My own prediction, though, is that most of them will be native the way Zed is native, and only a few the way Sketch or Mimestream are. The hard part has always been knowing the Mac (or any platform) well enough, and caring enough, to make something that feels like it belongs there.

A lost art

You know, there was a time when this was just how Mac apps were made. Through the mid-2000s and into the early iPhone years, the Mac was a small slice of the market. I grew up on Windows, like almost everyone I knew, and I was a teenager before I came across my first Mac. Next to rows and rows of Dells buried in cables, that Bondi Blue iMac, and later the aluminium one, looked like they’d landed from another planet (which, in retrospect, was very much the point). Using one was just as unfamiliar. Nothing was where I expected it to be, and it seemed to get everything backwards. Then, once I’d spent some real time with one, it slowly clicked, and I realised it wasn’t the one getting everything backwards.

I don’t think I was alone in that. People went out of their way to choose the Mac, and they stayed because they’d fallen for it. Everything felt as if it had been made specifically for you. Most people making software for the Mac had come to it the same way, and they were building for people like them. That’s why almost everything you downloaded fitted right in: the people making it wanted it to.

Some of that’s still true, but less than it used to be. The Mac is far more common than it was, and in some industries, it’s the computer people reach for first. That’s made it too important to leave out, so it’s become one more place an app has to be, alongside Windows, the web, and every phone out there. There are still teams building with the old care, but they’re up against economics that reward one codebase stretched across every screen, with little thought for how it feels on any one of them.

Nobody needed a word for “Mac-assed” back then. But if we’re all going native again, that’s the native I’m holding out hope for.