← Back to the journal

Engineering

React Native vs. Native Swift/Kotlin: How We Choose for a New App

"Should we build native or React Native?" is one of the first questions almost every founder asks, and it usually gets an opinionated, one-size-fits-all answer from whoever's in the room. The honest answer depends on what the app actually needs to do, not on which stack a given engineer prefers.

What React Native actually is today

React Native lets you write one JavaScript or TypeScript codebase that ships to both iOS and Android. The framework has matured significantly: the New Architecture replaces the old asynchronous JavaScript bridge with Fabric (a rewritten renderer) and TurboModules (synchronous native module access), and the Hermes JavaScript engine improves startup time and memory use over the old JavaScriptCore path. Combined with Expo's tooling, spinning up a cross-platform app and getting it building on both stores is faster than it was even two or three years ago.

What native still gives you

Native Swift/SwiftUI on iOS and Kotlin/Jetpack Compose on Android still win in a specific set of situations: day-one access to brand-new OS APIs (new ARKit capabilities, Live Activities, widgets, visionOS support) without waiting on a community bridge library to catch up; heavy camera, AR, or on-device machine-learning workloads where you want direct, unmediated access to AVFoundation, ARKit, ARCore, or Core ML/NNAPI; complex custom animation and gesture work where a JavaScript layer adds real overhead; and platform-native design idioms that make an app feel genuinely "at home" rather than merely functional on each OS.

Where React Native wins

For a business app whose core value is CRUD workflows, content display, forms, and standard navigation — the shape of most internal tools, marketplaces, and content apps — React Native lets one team ship both platforms from a single codebase, with a much larger pool of hire-able generalist engineers than native iOS-and-Android specialists combined. If you're also building a web app and want to share business logic, that overlap compounds the advantage.

Flutter, briefly

Flutter is a legitimate third option: it uses Dart and renders through its own engine (historically Skia, moving to Impeller) rather than mapping to native platform widgets. The tradeoffs land in a similar place to React Native — strong cross-platform velocity, a smaller native-feeling ceiling than fully native — with a smaller hiring pool for Dart specifically compared to JavaScript/TypeScript.

Our actual decision framework

  • Heavy camera, AR, depth sensing, or on-device ML as the core feature → native. When we built SurfaceIQ, a surface-scanning app using ARKit/ARCore depth capture and real-time image analysis, we wrote the capture and analysis pipeline natively per platform (with the pure math ported line-for-line between Swift and Kotlin) specifically because that workload needed direct hardware access.
  • A straightforward business or content app on a tight timeline → React Native, one team, both platforms at once.
  • You're also shipping a web app and want shared business logic → React Native (or a shared TypeScript layer) to avoid maintaining the same logic three times.
  • You're launching on one platform first and want to move as fast as possible on that platform specifically, without cross-platform overhead → native for that platform, with the second platform as a later, separately-scoped phase.

Hiring realities most founders underweight

Stack choice is also a hiring decision, and it's worth being honest about how that market actually looks. React Native and TypeScript draw from the much larger pool of web-adjacent engineers, which generally means faster hiring and a wider range of contractor and agency options. Native iOS and Android specialists are a smaller, more specialized pool — strong ones are excellent, but harder to source quickly, and a team that hires one strong Swift engineer and one strong Kotlin engineer is effectively running two parallel hiring searches instead of one.

Can you switch later?

Starting cross-platform and moving specific features to native later is realistic — React Native supports native modules precisely so you can drop into Swift or Kotlin for the one screen or workload that needs it, without rewriting the whole app. Starting native and later adding a cross-platform layer is a heavier lift, since you're retrofitting shared logic onto two codebases that have already diverged. If there's real uncertainty about which platform will matter most, starting cross-platform and hardening specific native modules as needs emerge is usually the lower-risk path.

Neither stack is categorically "better." The honest framing is: what does the app need to do in its hardest, most demanding feature, and does the team have (or can it hire) the skill set that stack requires? Answer that first, and the framework question mostly answers itself.

More from the journal