Mobile Apps
Mobile Apps
There are 3.5 billion smartphone users and two dominant app distribution platforms with combined revenues exceeding $150 billion. Understanding how mobile apps are built, distributed, and monetized is essential for any technology leader — whether you are buying development services, managing a team, or evaluating a product.
The Mobile Landscape
iOS and Android represent 99% of the global smartphone market. iOS users monetize at 2–3x the rate of Android users in North America and Europe. Android dominates in emerging markets. For most B2C products targeting North American consumers, iOS is the higher-priority platform.
The two fundamentally different ways to build for mobile:
Native development: write platform-specific code (Swift for iOS, Kotlin for Android). You get maximum performance, complete access to all platform APIs, and native UI components that behave exactly as users expect. You also maintain two separate codebases, which roughly doubles engineering effort.
Cross-platform development: write code once and compile/render to both platforms. React Native and Flutter are the dominant options. You trade some platform fidelity and performance ceiling for dramatically reduced development cost.
React Native in Depth
React Native renders actual native UI components — it does not use a WebView. When you write <View>, it creates a UIView on iOS and android.view.View on Android. This is fundamentally different from hybrid apps (Cordova, Ionic) that render HTML inside a WebView.
The original React Native architecture had a JavaScript bridge: JS and native ran on separate threads and communicated via a JSON-serialized message queue. This was asynchronous, adding latency to every native interaction and causing the "janky" animations that gave React Native a poor performance reputation.
The New Architecture (stable in 2024) replaces the bridge with JSI (JavaScript Interface), which allows synchronous direct calls between JS and native code. Combined with Fabric (the new rendering engine) and TurboModules (lazy-loaded native modules), React Native apps built on the New Architecture achieve performance that is within ~10–15% of native for most use cases.
When to Choose Native vs. React Native
Choose native (Swift/Kotlin) when:
- The app is animation-heavy (games, advanced transitions, real-time graphics)
- You need access to bleeding-edge platform APIs (new iOS features available months before React Native supports them)
- The team is already native-proficient and cross-platform code sharing is not a priority
- Apple Watch, widgets, and live activities are core features (React Native support is limited)
Choose React Native when:
- You want one team and one codebase for iOS and Android
- Your team is already proficient in JavaScript/TypeScript
- The app is primarily data-driven (forms, lists, CRUD operations)
- Shipping speed is critical and you cannot staff two native teams
- Web code sharing (React components) is valuable
Choose Flutter when:
- You want pixel-perfect custom UI that looks identical on both platforms (Flutter renders to a custom canvas, not native components)
- The team is comfortable with Dart
- Web + mobile + desktop from a single codebase is a requirement
The App Distribution Model
iOS: all apps must be distributed through the App Store (sideloading is restricted to Enterprise accounts and select EU markets under DMA compliance). Apple takes 30% of in-app purchase revenue (15% for businesses with less than $1M/year in Apple-ecosystem revenue). Apple's review is mandatory and takes 24–72 hours per submission.
Android: Google Play is the primary distribution channel, but Android supports sideloading (installing APKs directly). Google takes 15% of the first $1M in annual Play-mediated revenue, then 30%. Play review takes 1–5 days.
Performance Profiling
Mobile app performance problems fall into three categories:
- Rendering: too many re-renders, missing memoization, heavy components in scroll lists. In React Native, FlatList with
keyExtractorandgetItemLayoutis mandatory for smooth performance on large lists. - JS thread blocking: heavy computation on the main JS thread blocks UI updates. Move to a background thread using
InteractionManageror web workers (in new arch). - Network: slow API responses causing blank states. Implement optimistic updates (update UI immediately, confirm in background) and skeleton loading states to mask latency.
Offline-First Design
Mobile users lose network connectivity. Your app's behavior during network loss defines user experience quality. Offline-first apps:
- Cache critical data locally (SQLite via react-native-mmkv or WatermelonDB)
- Queue actions taken offline and sync when connectivity returns
- Surface clear, non-alarming UI for offline states
- Handle sync conflicts (user edited on mobile and web simultaneously) with a defined resolution strategy