Skip to content
HANA PlatformHANARAD

Mobile app stack

React Native and Flutter app development — native when it matters

We pick the mobile framework that fits your product, not the one we happen to like. Every option has a fixed, proven core stack and the same security baseline.

Choosing a framework

Which framework we use when

React Native and Flutter app development covers most products with one shared codebase for iOS and Android. Native Kotlin and Swift are reserved for single-platform apps that need deep integration with the device. Each app uses exactly one framework — we never mix two inside the same app.

  • Cross-platform, fast delivery, team knows React/TypeScript

    Framework
    React Native (Expo, TypeScript)
    Why
    One TypeScript codebase for iOS and Android that shares types and skills with our web stack.
  • Cross-platform with strong custom UI and animation

    Framework
    Flutter (Dart, Riverpod)
    Why
    Its own rendering engine draws pixel-perfect custom interfaces consistently on both platforms.
  • Android-only with deep platform integration

    Framework
    Native Android (Kotlin, Jetpack Compose)
    Why
    Full access to Android features such as home-screen widgets, Wear OS and NFC.
  • iOS-only with deep platform integration

    Framework
    Native iOS (Swift, SwiftUI)
    Why
    First-class access to Apple frameworks such as widgets and Live Activities.
  • Existing native app gaining a new feature

    Framework
    Stay native (Kotlin or Swift)
    Why
    Adding a second framework to a working app raises cost and risk, so the new feature is built natively.

Core stack

The libraries behind each framework

Every developer working in a framework uses the same core libraries, so any of them can maintain or extend the app.

TypeScript

React Native

Chosen for cross-platform apps when speed of delivery matters and the team or product already works with React and TypeScript.

UI
Expo development builds (not Expo Go), React Navigation and NativeWind styling
State management
TanStack Query for server data; component state first, Zustand for small shared app state
Networking
Typed client generated from our OpenAPI specification, wrapped in TanStack Query hooks; forms with React Hook Form and Zod
Local data
AsyncStorage or MMKV for cached data and settings only — never for tokens
Secure storage
expo-secure-store or react-native-keychain, backed by Keychain on iOS and Keystore on Android
Testing
Jest and React Native Testing Library; Maestro or Detox for end-to-end flows
CI/CD
EAS Build and EAS Submit; EAS Update over the air for JavaScript-only fixes, with any native change going through store review

Dart

Flutter

Chosen when the experience depends on highly custom, animated UI that must look identical on iOS and Android.

UI
Flutter with Material 3, one shared theme with light and dark mode, and go_router navigation
State management
Riverpod (flutter_riverpod with riverpod_generator)
Networking
Dio with a typed client and models built from our OpenAPI specification
Local data
Drift (SQLite) for offline data; shared_preferences for non-sensitive settings only
Secure storage
flutter_secure_storage (Keychain / Keystore)
Testing
flutter_test and mocktail for unit and widget tests; integration_test for end-to-end flows; golden tests for key visuals
CI/CD
Fastlane or Codemagic pipelines

Kotlin

Native Android

For Android-only products that need deep platform integration, such as widgets, Wear OS or NFC.

UI
Jetpack Compose with Material 3, type-safe Compose Navigation and Coil for images
State management
MVVM with ViewModel, Kotlin Coroutines and Flow; Hilt for dependency injection
Networking
Retrofit with OkHttp and kotlinx.serialization
Local data
Room for offline data; Jetpack DataStore for non-sensitive preferences
Secure storage
Android Keystore with EncryptedSharedPreferences
Testing
JUnit5, MockK and Turbine for unit tests; Compose UI tests and Espresso
CI/CD
Gradle (Kotlin DSL, version catalogs) with Gradle Play Publisher or Fastlane

Swift

Native iOS

For iOS-only products that need the latest Apple frameworks, such as widgets, Live Activities or deep device integration.

UI
SwiftUI with NavigationStack; UIKit only to fill a specific gap
State management
MVVM with @Observable view models and Swift Concurrency (async/await, actors)
Networking
URLSession with async/await and Codable
Local data
SwiftData (Core Data on older projects); UserDefaults for non-sensitive settings only
Secure storage
Keychain Services
Testing
Swift Testing and XCTest for unit tests; XCUITest for UI flows
CI/CD
Fastlane with Xcode Cloud or GitHub Actions, delivering through TestFlight

Mobile security baseline

Six protections every app ships with

Mobile apps run on devices you don't control, so security is designed in from the first sprint, not bolted on before launch.

  • Secure token storage

    Tokens live only in Keychain on iOS and Keystore-backed storage on Android — never in plain preferences or files.

  • Short-lived JWT + rotating refresh

    Access tokens expire quickly and refresh silently in the background. If a refresh fails, the user is signed out.

  • Extra protection for sensitive apps

    Finance, health and credential apps add certificate pinning with a planned rotation, and hide sensitive screens in the app switcher.

  • No secrets inside the app

    Third-party API keys stay on our servers and are called through the backend, so they cannot be extracted from the app.

  • Deep links are verified

    A link that opens the app never triggers a privileged action on its own — the server checks the user is allowed first.

  • Obfuscated release builds

    Release builds are minified and obfuscated, making reverse engineering of business logic significantly harder.

Quality standards

What every app has to meet before launch

Security is only part of a good app. These standards apply to every framework, so the app works for all of your users, on good and bad connections.

  • Accessible by default

    Screen readers can complete every key journey, text follows the phone's size setting and tap targets are large enough to hit.

  • Clear offline behaviour

    Each feature is designed as online-only, cached or fully offline. Changes made offline are queued and synced safely later.

  • Performance budgets

    The first screen should be usable in about two seconds on a mid-range phone, with long lists and images loaded efficiently.

  • No blank or broken screens

    Every screen that loads data shows a clear loading, empty and error state, with a way to retry.

  • Tested on real journeys

    Automated end-to-end tests cover sign-up, login and core actions, and we test on the oldest supported OS version before release.

  • Crash monitoring

    Crash reporting is live from the first build, and a drop in the crash-free session rate blocks the release.

Release practices

How updates reach your users safely

Store releases cannot be undone instantly, so every release follows the same controlled process.

  • Separate test and live builds

    Development, staging and production builds connect to their own servers and look different, so testers never touch live data.

  • Automated checks before signing

    A release is signed only after automated linting, tests and a clean build pass in CI.

  • Staged rollouts

    New versions reach a small share of users first through Play staged rollouts and App Store phased releases.

  • A rollback plan, every time

    Before a rollout starts we know how to pause it or ship a fix, so a problem reaches as few users as possible.

One backend

Every app consumes the same versioned REST API

Our mobile apps use the same /v1 REST API as the web app, described by one OpenAPI specification with one error format. Business rules and permissions are enforced on the server, never only in the app, and each app’s data models are generated or mirrored from that same specification. One set of rules means lower cost, no drift between platforms and safer releases.

Explore the backendWeb & backend stack

FAQ

Mobile app stack: frequently asked questions

Not sure which framework fits?

Share your app idea and target users. In a free 30-minute consultation we will recommend a framework and explain the trade-offs in plain language.