Skip to content
Engineering deep-divesAll articles

Cross-Platform App Development: Architecture & Tradeoffs

Cross-platform app development lets one engineering squad ship to both iOS and Android without maintaining two codebases. Here is how modern runtimes execute on silicon, how to structure the 85/15 shared-to-native boundary, and when native code is still mandatory.

Artem Zaitsev
Artem ZaitsevCTO · Idealogic
Author: Artem ZaitsevPublished: Updated: Reading time: 18 minHow we write →
On this page
Idealogic: cross-platform app development frameworks compared

Cross-platform app development is the engineering discipline of building and shipping a mobile application to both Apple's iOS and Google's Android from a single primary repository, rather than funding, staffing, and synchronizing two separate native codebases in Swift and Kotlin. At the systems level, modern cross-platform engineering works by decoupling your application's domain logic, networking, state tree, and layout definitions from the host operating system's proprietary UI toolkit, then binding the two together through compiled C++ interfaces, Ahead-of-Time (AOT) machine code, or GPU-accelerated rendering engines.

Five years ago, choosing a shared codebase meant accepting visible runtime compromises: dropped frames on long lists, awkward scroll physics, and asynchronous serialization bottlenecks whenever JavaScript needed to read a device sensor. In 2026, those structural bottlenecks have been engineered out of the leading runtimes. This guide examines how cross-platform mobile development executes on silicon today, compares the four runtime architectures in production, shows how our engineers at Idealogic structure the 85/15 boundary between shared code and native Swift or Kotlin modules, and walks through the monorepo and CI/CD pipeline required to ship both store binaries reliably.

The short version

  • Four distinct runtime models exist: React Native's New Architecture maps TypeScript components to real UIView and android.view.View instances via C++ JSI; Flutter's Impeller engine compiles Dart to native ARM64 machine code and draws every pixel directly over Metal and Vulkan; Kotlin Multiplatform (KMP) compiles shared domain logic into JVM bytecode and LLVM native frameworks behind native SwiftUI and Jetpack Compose screens; and Capacitor wraps a web DOM inside a native WebView shell.
  • The realistic code-sharing ratio is 85/15, never 100/0: Production apps share 100% of API clients, local SQLite schemas, state machines, and 85%+ of UI screens, while isolating 10% to 15% of code for platform-specific hardware bridges (BLE, NFC, HealthKit, biometric enclaves, and OS extensions).
  • Synchronous C++ and AOT compilation killed the "bridge tax": By eliminating JSON serialization queues (React Native JSI/TurboModules) and runtime shader compilation stutter (Flutter Impeller), modern cross-platform builds hold 60fps to 120Hz ProMotion frame budgets across standard product interfaces.
  • Platform feel comes from physics and navigation, not duplicated business logic: Users judge an app's "nativeness" by scroll deceleration rates, edge-swipe back gestures, haptic feedback, and keyboard avoidance. A shared codebase that respects platform-adaptive navigation primitives feels indistinguishable from dual native apps.
  • Dual-store CI/CD and OTA updates compress release cycles: A unified pipeline verifies one pull request against both iOS and Android E2E test suites, compiles signed .ipa and .aab artifacts, and uses over-the-air hotfix channels to patch logic bugs without waiting 48 hours for store review.

How Cross-Platform App Development Executes on Silicon in 2026

To make sound architectural decisions in mobile app development, you have to look past marketing slogans like "write once, run anywhere" and inspect what happens inside the CPU, memory space, and GPU pipeline when a user taps the screen. Every mobile operating system exposes two primary surfaces to an application: the visual compositor (CoreAnimation and Metal on iOS; SurfaceFlinger, Skia, and Vulkan on Android) and the system service daemons (location, camera, Bluetooth, secure keychain, push notifications, and background task schedulers).

When you build a pure native application, your Swift code talks directly to Apple's Objective-C/Swift runtime and UIKit or SwiftUI, and your Kotlin code talks directly to the Android Runtime (ART) and Jetpack Compose. When you build a cross-platform application, the framework must bridge or replace one or both of those surfaces. In 2026, production frameworks divide into four concrete runtime architectures.

Every cross-platform tool chooses where to place the abstraction boundary: at the native UI view layer, the GPU canvas, the business logic boundary, or the browser DOM.

1. OEM Native View Mapping via C++ JSI (React Native)

In React Native app development, your UI is not drawn inside a browser or on a synthetic canvas. When you render a <View>, <Text>, or <ScrollView> in TypeScript, the runtime instantiates an actual iOS UIView or UITextView on an iPhone and an actual android.view.ViewGroup or android.widget.TextView on an Android device.

Historically, React Native coordinated these native views across an asynchronous JSON bridge: the JavaScript thread serialized layout mutations into a JSON string, queued them across a thread boundary, and waited for the main UI thread to deserialize and apply them. Under heavy scroll events or gesture animations, that queue congested and dropped frames.

Under React Native's New Architecture, which is the standard production baseline in 2026, that asynchronous bridge is gone:

  • Hermes Bytecode Engine: JavaScript and TypeScript source files are precompiled at build time into optimized Hermes bytecode (.hbc), eliminating runtime parsing and JIT compilation spikes during cold start.
  • JavaScript Interface (JSI): Written in C++, JSI allows the Hermes engine to hold direct memory references (C++ HostObjects) to native Objective-C++ and Kotlin/JNI objects. JavaScript can invoke methods on native objects synchronously on the same thread without JSON serialization.
  • Fabric Renderer: The UI layer shares an immutable C++ shadow tree between JavaScript and the host OS. Using Yoga (a C++ Flexbox layout engine), Fabric calculates layout geometry in C++ and mounts real OEM views directly, enabling synchronous layout reads and smooth 120Hz gesture interception.
  • TurboModules & Codegen: Native hardware modules load lazily only when first invoked, and their C++ glue code is generated automatically from strongly typed TypeScript specs (Codegen), preventing type mismatches across the native boundary.

You can explore the runtime fundamentals further in our React Native knowledge base guide.

2. Custom AOT Engine and GPU Canvas Rendering (Flutter)

Flutter app development takes the opposite architectural stance. Instead of asking iOS to create a UIButton or asking Android to create a MaterialButton, Flutter bypasses the OEM widget toolkits entirely. All it asks from the host operating system is a blank hardware-accelerated surface (CAMetalLayer on iOS, Surface backed by Vulkan or OpenGL ES on Android) and a stream of raw touch, keyboard, and lifecycle events.

As detailed in the Flutter architectural overview, the entire widget tree, layout pass, animation interpolation, and compositing pipeline live inside the compiled Flutter engine:

  • Dart AOT Compilation: For release builds, Dart code is compiled Ahead-of-Time (AOT) directly into native ARM64 or x86_64 machine instructions. There is no interpreter or bytecode virtual machine parsing scripts at runtime.
  • Impeller Rendering Engine: Early versions of Flutter used the Skia graphics engine, which compiled GLSL shaders at runtime the first time a complex animation played, causing first-run frame stutter ("shader compilation jank"). The Impeller rendering engine precompiles a smaller, fixed set of shaders offline during the build step and targets modern low-level graphics APIs (Apple Metal and Android Vulkan) directly.
  • Visual Consistency vs Platform Imitation: Because Flutter draws every pixel itself, a custom interface looks pixel-identical on an iPhone 16 Pro and a mid-range Android phone. The tradeoff is that when Apple or Google updates system UI conventions, Flutter's Cupertino and Material widget libraries must replicate those changes in Dart rather than inheriting them automatically from the OS binary.

See our Flutter knowledge base overview for a breakdown of widget trees and isolate concurrency.

3. Shared Native Binary Logic with Native UI (Kotlin Multiplatform)

JetBrains Kotlin Multiplatform (KMP) draws the abstraction boundary underneath the user interface. In a classical KMP architecture, you write 100% of your domain models, REST/gRPC networking (Ktor), local database persistence (SQLDelight or multiplatform Room), serialization (kotlinx.serialization), and presentation view-models in common Kotlin.

At compile time:

  • For Android, the Kotlin compiler outputs standard JVM bytecode that runs natively inside the Android app alongside Jetpack Compose.
  • For iOS, the Kotlin/Native compiler uses LLVM to compile that exact same Kotlin code into a standalone .xcframework binary exposing Objective-C/Swift headers, which your iOS engineers call directly from SwiftUI.

Teams that want to share UI as well can add Compose Multiplatform, which renders shared Kotlin UI code via Skiko (Skia for Kotlin), though most enterprise KMP adopters choose KMP because they want zero-compromise native SwiftUI and Jetpack Compose views backed by a single verified business logic library.

4. Embedded WebView Containers and PWAs (Capacitor, Ionic, Web Standards)

The fourth architectural tier runs standard web code (HTML5, CSS3, and JavaScript or TypeScript) inside an operating system browser engine: WKWebView on iOS and android.webkit.WebView (Blink/V8) on Android.

  • Hybrid WebView Wrappers (Capacitor / Ionic): Package your bundled web assets inside a real native .ipa and .aab binary and inject a JavaScript-to-Native message bridge (window.Capacitor.nativeCallback) so the web page can trigger native camera sheets, biometric prompts, and push notifications.
  • Progressive Web Apps (PWAs): Skip the native binary wrapper and app stores completely. Governed by the W3C Service Workers specification and Web App Manifest standards, a progressive web app installs directly from Safari or Chrome to the user's home screen, caches assets for offline execution, and updates instantaneously on every deployment.
All three cross-platform approaches ship from one primary repository, but they place the boundary between shared code and host OS in different layers.

Side-by-Side Architectural Comparison Matrix

When our architecture team scopes a new product, we evaluate these four cross-platform runtimes across eight concrete technical dimensions. For a deeper head-to-head between the top two full-stack frameworks, see our dedicated React Native vs Flutter benchmark.

Architectural DimensionReact Native (New Arch + Expo)Flutter (Impeller + Dart AOT)Kotlin Multiplatform (KMP)Capacitor / PWA (WebView)
Primary LanguageTypeScript / JavaScriptDartKotlin (plus Swift for iOS UI)TypeScript / HTML / CSS
Execution RuntimeHermes Bytecode VM + C++ JSIAOT Compiled ARM64 Native BinaryJVM Bytecode (Android) + LLVM Native (iOS)WebKit Nitro (iOS) / Blink V8 (Android)
UI Rendering TargetReal UIView (iOS) & android.view.ViewCustom Impeller GPU Canvas (Metal/Vulkan)Native SwiftUI + Native Jetpack ComposeBrowser DOM & CSS Layout Engine
Native API BindingSynchronous C++ TurboModules (Codegen)Platform Channels / FFI / PigeonDirect Interop (JNI / Objective-C/Swift)Async JS Message Bridge / Web APIs
Typical Code Sharing85% to 92% (UI + Logic)88% to 95% (UI + Logic)55% to 70% (Logic only; 90% with Compose MP)95% to 100% across Web, iOS, Android
Baseline Binary Overhead~6 MB to 10 MB over native~9 MB to 15 MB (includes engine)~1.5 MB to 4 MB (LLVM runtime)~2 MB to 5 MB (Capacitor); 0 MB (PWA)
OTA Hotfix CapabilityNative support (JS/assets via EAS Update)Patch support via Shorebird (Dart binary diff)Store release required for compiled binaryInstant server deploy or live bundle reload
Developer Talent PoolMassive (62% JS/TS on Stack Overflow)Specialized (~6% Dart familiarity)Strong Android base (~9% Kotlin, plus Swift)Massive (any web frontend engineer)

Architecting the 85/15 Shared-to-Native Boundary in Production

The single biggest mistake inexperienced teams make in cross-platform mobile development is assuming that "single codebase" means engineers never touch Xcode, Swift, Android Studio, or Gradle. Every non-trivial mobile product eventually hits the boundary between cross-platform abstractions and operating system internals.

In our production builds at Idealogic, we design around an explicit 85/15 architectural split from day one. When you plan your mobile app architecture around this ratio, the 15% of platform-specific work remains clean, testable, and isolated instead of leaking Platform.OS === 'ios' conditionals across hundreds of UI files.

How senior cross-platform teams partition 100% shared domain layers, 85%+ shared UI components, and 15% isolated native modules.

Layer 1: 100% Shared Domain, Networking, and Offline Persistence

Everything below the view layer should be 100% platform-agnostic, aligning with the Android Developers official app architecture guidelines, which separate the Data and Domain Layers from UI elements:

  • API Transport and Auth Interceptors: REST, GraphQL, or WebSocket clients, OAuth2 token refresh queues, certificate pinning policies, and retry backoff algorithms are written once.
  • Local Database and Sync Engines: Whether you use SQLite via op-sqlite (C++ JSI binding in React Native), Drift (SQLite over dart:ffi in Flutter), or SQLDelight (in KMP), local relational tables, WAL mode (PRAGMA journal_mode=WAL;), migrations, and optimistic offline mutation queues execute identically on both platforms.
  • Domain Validation and State Machines: Form schemas (such as Zod in TypeScript), currency formatting, cart calculations, and finite state machines run inside the shared runtime with deterministic unit tests that execute in milliseconds on CI without booting a simulator.

Layer 2: 85% to 90% Shared UI with Platform-Adaptive Primitives

Your screens, component trees, design tokens, and accessibility labels are shared, while interaction primitives adapt to the host OS:

  • Tokenized Design Systems: Color tokens, typography scales, spacing grids, and border radii live in a single shared theme dictionary.
  • Platform-Adaptive Navigation: On iOS, stack navigators use interactive swipe-back gestures and modal sheets that respect safe-area insets and the Dynamic Island. On Android, the same route definition binds to Android 14+ predictive back gestures and system back-button handlers.
  • Input and Accessibility Ergonomics: Text inputs wire platform-specific keyboardType, autofill hints (oneTimeCode, username, password), VoiceOver/TalkBack semantics, and keyboard-avoiding scroll containers.

Layer 3: The 10% to 15% Native Hardware and OS Integration Layer

Whenever a feature touches hardware peripherals, background execution limits, or system surfaces outside the main application window, we isolate it behind a strongly typed interface in the shared codebase and implement the concrete adapter in Swift and Kotlin:

  1. Bluetooth Low Energy (BLE) and External Hardware: Medical sensors in healthtech apps, IoT controllers, and POS readers require GATT characteristic subscriptions, MTU negotiation, and background peripheral restoration (CBCentralManagerOptionRestoreIdentifierKey on iOS, foreground services on Android).
  2. Secure Enclave, Biometrics, and Attestation: Cryptographic keys in Apple's Secure Enclave (LocalAuthentication) and Android's Hardware-Backed Keystore (BiometricPrompt), plus hardware attestation via Apple App Attest and Google Play Integrity, never expose raw keys to the JS or Dart heap.
  3. In-App Purchases and Store Billing: Subscription entitlements hook into Apple StoreKit 2 and Google Play Billing Library v7.
  4. System Companion Surfaces: iOS Live Activities (ActivityKit), Dynamic Island widgets (WidgetKit), and Android Glance AppWidgets compile as standalone native targets in Xcode and Gradle that read shared data from an iOS App Group container or Android DataStore.

"The secret to a fast, maintainable cross-platform app is not trying to force 100% of your product into JavaScript or Dart. It is sharing the 85% of code that is undifferentiated business logic and UI layout, while giving the 15% of hardware-specific code a clean, typed Swift and Kotlin boundary."


Writing Custom Native Bridges and Managing Concurrency

A common concern when evaluating cross-platform vs native is what happens when an open-source plugin is unmaintained or when a vendor provides only native .xcframework and .aar SDKs. In 2026, writing custom native bridges and managing multi-threaded workloads is type-safe and deterministic.

Typed Native Modules in React Native and Flutter

  • React Native (Codegen + TurboModules): You define a TypeScript spec file (NativeBiometricSigner.ts) extending TurboModule. At build time, Codegen generates the C++ abstract interface, Objective-C++ protocol, and Kotlin base class. Synchronous methods execute in microseconds over JSI, while hardware I/O returns a typed Promise. Instead of pulling in a fragile community wrapper, a senior engineer writes 60 lines of Swift and 60 lines of Kotlin directly in your repository's modules/ directory.
  • Flutter (Pigeon + dart:ffi): For asynchronous host APIs (such as launching an iOS app or Android app payment sheet), Pigeon generates type-safe Dart, Swift, and Kotlin classes from a single schema file. For synchronous C/C++/Rust libraries (audio decoding, SQLCipher, local ONNX inference), dart:ffi binds directly to native symbols with near-zero marshaling overhead.

Threading and Concurrency Across Runtimes

  • React Native's Multi-Threaded Model: Execution splits across the Main UI Thread (UIKit/Android Views), the JavaScript Thread (Hermes VM with non-blocking generational GC), the C++ Shadow Thread (Yoga Flexbox layout), and UI Thread Worklets (react-native-reanimated), which run 120Hz gesture physics and camera frame processors on dedicated threads.
  • Flutter's Shared-Nothing Isolates: Flutter runs four primary task runners (Platform, UI, Raster/GPU, and I/O) and uses Dart Isolates (Isolate.run) with private memory heaps to parse large JSON payloads off the main UI isolate.
  • Kotlin Multiplatform Coroutines: KMP uses kotlinx.coroutines, mapping to JVM thread pools on Android and interoperating with Swift async/await and ARC on iOS.

Monorepo Architecture and Dual-Store CI/CD Release Automation

Where cross-platform engineering delivers its highest operational leverage is unifying your repository, shared schemas, and release pipelines.

Full-Stack Schema Sharing in a Monorepo

When a team builds a web frontend in React/Next.js, a backend in Node.js or Go, and a mobile app in React Native (with Expo) inside a Turborepo or Nx monorepo:

  1. Shared API Contracts: OpenAPI specs, GraphQL fragments, or tRPC router types live in packages/api-contracts. If a backend engineer renames a field on a transaction payload in a fintech app, the mobile TypeScript build fails immediately in the same pull request.
  2. Shared Domain Validation: Currency math, date utilities, and Zod schemas live in packages/domain and run across web, mobile, and server workers.
  3. Design Token Sync: Figma variables export to packages/design-tokens, compiling into CSS variables for web and typed style objects for mobile.

Automated Dual-Store CI/CD Pipeline and OTA Rules

Cross-platform development eliminates "release skew" between iOS and Android when paired with a single CI/CD pipeline:

Pipeline StageExecution EnvironmentVerification & Output
1. Static Analysis & Unit TestsLinux Container (~90s)ESLint/Biome or dart analyze, TypeScript/Dart compiler checks, Jest/Vitest or flutter test.
2. Native Fingerprint CheckLinux Container (~15s)Hashes Podfile.lock, gradle.lockfile, and native modules to decide between binary build vs OTA update.
3. Simulator E2E RegressionmacOS Runner & Linux KVMRuns Maestro or Detox E2E user flows against both iOS Simulator and Android Emulator.
4. Signed Binary BuildmacOS (EAS / Fastlane)Compiles signed .ipa (TestFlight) and .aab (Google Play) with automated symbol uploads.
5. OTA Hotfix PushEdge CDN (EAS / Shorebird)Pushes signed JS bytecode or Dart patch bundles pinned to matching runtimeVersion binaries.

When using over-the-air updates (Expo EAS Update or Shorebird), teams must adhere to section 3.3.2 of the Apple App Store Review Guidelines: OTA patches are strictly for bug fixes, copy updates, and layout adjustments within the app's reviewed scope, never for shipping undisclosed features or unsigned native machine code.


Performance Profiling, Cost, and When to Go Native Instead

In 95% of performance audits we run on sluggish cross-platform apps, the root cause is not the C++ JSI layer or Dart compiler; it is preventable architectural mistakes:

  1. Thread Starvation: Parsing massive JSON responses on the main JS/UI isolate. Offload heavy data work to background isolates or SQLite queries, and run gesture animations via UI-thread worklets.
  2. Unvirtualized Lists: Mounting hundreds of complex cards at once. Use cell-recycling lists (FlashList in React Native, SliverList.builder in Flutter) with hardware-decoded image caching (expo-image).
  3. Cold Start Bloat: Initializing analytics SDKs synchronously before the first frame mounts. Enable Hermes bytecode precompilation, minimize dynamic iOS frameworks, and defer non-critical SDK init until after the first screen renders.

Team Topology Economics and the 5 Native Triggers

According to Eurostat hourly labour cost data (lc_lci_lev) and U.S. Bureau of Labor Statistics software developer compensation benchmarks, senior engineering compensation is the dominant cost driver in mobile software. Running one unified cross-platform squad instead of separate iOS and Android teams reduces initial MVP build cost by 30% to 40% and cuts 3-year maintenance cost by 35% to 45%. See our native vs cross-platform app development TCO model and our mobile app development cost guide for full budget tables.

However, we advise clients to skip cross-platform and build pure native iOS (Swift/SwiftUI) and Android (Kotlin/Compose) when a product hits any of these five triggers:

  1. Real-Time Audio DSP, Custom Shaders, or Spatial AR/3D: Sub-16ms audio workstations (CoreAudio/Oboe), 4K video editors, or ARKit/RealityKit spatial apps.
  2. OS-Surface-First Products: Apps where 70%+ of usage lives inside WatchOS, CarPlay, interactive WidgetKit, or system keyboards.
  3. Deep System Daemons & Continuous Medical BLE: Headless VPN tunnels (NetworkExtension), custom MDM launchers, or continuous background telemetry patches.
  4. Single-Platform Strategy: Products targeting only iOS or only Android for the next 18+ months.
  5. Strict Binary Size Caps: Apple App Clips and Google Play Instant experiences with tight 15 MB to 50 MB uncompressed binary limits.

For a complete roadmap from initial scoping to store launch, read our blueprint on how to build a mobile app.

Planning a cross-platform mobile build or auditing an existing codebase?
Talk to a senior mobile team

Occasional field notes on building software, no spam

Protected by Cloudflare Turnstile · Privacy · Terms

Artem Zaitsev
Artem ZaitsevCTO · Idealogic Development OÜ

CTO and Co-founder at Idealogic. Directing engineering, systems architecture, security, and full-stack delivery across web, mobile, and blockchain.

Frequently asked questions

  • Cross-platform app development is the practice of writing a single mobile codebase that compiles or binds to both iOS and Android binaries. Instead of maintaining separate Swift and Kotlin codebases, teams use runtimes that map shared code to real UIKit and Android Views via C++ bindings (React Native), draw directly onto a Metal or Vulkan GPU canvas (Flutter), share compiled native logic libraries (Kotlin Multiplatform), or render inside an embedded system WebView (Capacitor).

  • In a production cross-platform build, engineering teams typically share 85% to 92% of the codebase across iOS and Android. State management, REST or GraphQL networking, local SQLite storage, authentication flows, and standard screen layouts are written once. The remaining 8% to 15% consists of platform-specific native modules for hardware APIs like Bluetooth Low Energy, NFC, HealthKit, biometric enclaves, push notification services, and store billing.

  • First-generation cross-platform apps either ran inside slow mobile WebViews or serialized JSON messages asynchronously across an execution bridge, which dropped frames during rapid scrolling or gesture interactions. Modern runtimes removed those bottlenecks. React Native replaced its JSON bridge with synchronous C++ JavaScript Interface (JSI) bindings and the Fabric renderer, while Flutter replaced Skia's runtime shader compilation with the precompiled Impeller rendering engine.

  • Cross-platform frameworks expose hardware sensors and operating system APIs through typed native module bindings. In React Native, Codegen and TurboModules let TypeScript call Swift or Kotlin methods synchronously over C++. In Flutter, Platform Channels and the Pigeon code generator pass structured messages between Dart isolates and host OS threads. Teams write thin native wrappers once and call them from shared business logic.

  • Yes, provided the application delivers genuine native functionality rather than simply repackaging a mobile website inside an app shell. Apple App Store Review Guideline 4.2 rejects thin WebView wrappers that behave like Safari bookmarks. Apps built with React Native, Flutter, or Kotlin Multiplatform compile into standard IPA binaries, use native system permissions, support offline persistence, and pass App Store review on the same footing as Swift apps.

  • A well-architected cross-platform app separates visual brand identity from operating system ergonomics. Typography scales, color palettes, spacing units, and elevation tokens stay identical across iOS and Android. Navigation mechanics and physics adapt to the host platform: iOS users get edge-swipe back gestures, spring physics, and Cupertino sheets, while Android users get predictive back gestures, Material ripple feedback, and system back-stack handling.

  • A cross-platform CI/CD pipeline runs a single shared linting, TypeScript or Dart static analysis, and unit test stage before fan-out into macOS workers (for Xcode archiving and TestFlight upload) and Linux workers (for Gradle AAB compilation and Google Play internal tracks). Teams pair store releases with signed over-the-air bundle updates via Expo EAS Update or Shorebird for instant JavaScript or Dart hotfixes.

  • Avoid full-stack cross-platform frameworks when your core product relies on sub-16ms real-time audio DSP, custom Metal or Vulkan 3D shaders, ARKit or RealityKit spatial computing, or heavy OS companion extensions like WatchOS, CarPlay, and interactive WidgetKit surfaces. In those cases, writing direct Swift and Kotlin avoids writing and maintaining more custom bridge code than shared application code.

Still unanswered
Ask us directly

A senior engineer replies under 4 hours.

Related expertise