Flutter
Flutter / Dart: one codebase for iOS and Android, plus web and desktop
Google’s UI toolkit in Dart. It draws every pixel itself, so a custom brand design and animation look the same on iOS and Android. One team, one codebase, and web and desktop builds from the same code. The trade-offs: a smaller hiring pool than JavaScript, and new platform features arrive through plugins, sometimes later.
React Native
React Native (incl. Expo): JavaScript / TypeScript, native UI components
Meta’s framework in JavaScript or TypeScript, with Expo as the default toolchain and the new architecture on by default. It renders real platform components, so standard screens look at home on each OS. It shines when your team already writes React or when the app shares logic with a web product. Heavy custom graphics are its weaker side.
Native iOS + Android
Swift / SwiftUI for iOS and Kotlin / Compose for Android: two codebases
Two apps, each in the platform’s own language and UI toolkit. You get every new OS feature on day one, the best access to hardware such as Bluetooth, health data, widgets and the camera, and the most familiar feel. The price is two codebases: roughly 1.4–1.8 times the build cost of a cross-platform app and two teams to keep in step.
Kotlin Multiplatform
Kotlin Multiplatform: shared business logic, native or Compose Multiplatform UI
Shares business logic, networking and data in Kotlin while each platform keeps a native UI, or uses Compose Multiplatform for shared screens. It suits teams that already have native apps or Android engineers and want less duplication without a full rewrite. The ecosystem is younger, so plan extra time for tooling and iOS integration.
PWA
Progressive Web App, optionally packaged with Capacitor or TWA for the stores
A web app that installs to the home screen and works offline within browser limits. It is the cheapest and fastest route when a link or QR code is enough and the app is mostly content and forms. On iOS, push, background work, storage and device access are more limited than in a native app, and store listings need a wrapper.