· 4 min read
Why we build native
Every platform has a grain. Software that runs with it feels like it belongs; software that runs across it never quite does.
There is a moment, a few seconds into using a new app, when you decide whether it belongs on your device. Nobody says it out loud. You notice that a text field didn’t behave the way text fields do, or that a window forgot where you put it, or that the back gesture did something slightly wrong. None of these is a bug. Together they are the difference between software that is at home and software that is visiting.
We call that difference grain. Every platform has one: the conventions it has accumulated, the frameworks it ships, the way things are expected to move and respond. On iPhone it is momentum scrolling, sheets that rise from the edge your thumb is already near, and a keyboard that never covers the field you are typing in. On the Mac it is the menu bar, a shortcut for everything, and windows that keep their size and place. Windows has its own answers to the same questions, and they are just as deliberate.
The cost of one codebase
Cross-platform toolkits promise to write a product once and ship it everywhere. Sometimes that is the right trade, and we won’t pretend otherwise. But the abstraction always has a price, and the person using the software pays it. A toolkit that targets four platforms can only offer what they have in common, so each one gets the common denominator plus a list of patches. Text selection is approximated. Accessibility is reimplemented, often partially. Scrolling physics are imitated, nearly. Each gap is small. People feel all of them.
Native code also ages better. When a platform adds a capability — a new input method, a system-wide feature, a new accessibility setting — native apps tend to inherit it for free or with a few lines of work. Abstracted apps wait for their toolkit to catch up, and some never do.
What native means here
It means each platform gets its own interface, written with that platform’s own frameworks: Swift and SwiftUI on Apple platforms, with AppKit where the Mac needs it, and the native Windows stack on Windows. It means designing with each platform’s conventions rather than laying a house style over the top. And it means testing on real devices with real input, because a design that looks right in a mock-up can still feel wrong under a thumb.
It does not mean writing everything twice. The parts of a product that are about what it does — the data, the sync, the logic of a feature — can be shared with care. The parts that are about how it feels belong to the platform.
Software should feel at home on the device it was made for.
That sentence sits at the top of how we work, and most of our decisions fall out of it. Building native takes more effort. We think the effort is the point.