Skip to content

Engineering · 13 min read

Cross-Platform Libraries and When to Use Each

React Native, Flutter, Ionic, Electron, and the rest share one goal. Ship on more than one platform without maintaining completely separate codebases. Here is how they differ in practice.

Featured image for Cross-Platform Libraries and When to Use Each

Cross-platform development means you write a large share of your product once and run it on multiple operating systems. That usually means iOS and Android for phones, sometimes the web, sometimes Windows and macOS for desktop.

The label sounds simple. The tools are not interchangeable. React Native, Flutter, Ionic, and Electron solve different problems with different trade-offs. Picking the wrong one costs months.

This post is a practical map: what each stack is, what it is good at, and where it breaks down.

What "cross-platform" actually means

There are three common patterns:

PatternIdeaExamples
Shared UI + native shellOne codebase renders with native widgets or a native bridgeReact Native, Flutter
Web tech in a native wrapperHTML/CSS/JS inside a WebView or similarIonic, Capacitor, older Cordova apps
Web tech in a desktop shellChromium (or similar) packaged as an appElectron, Tauri

None of these give you 100% identical apps on every platform. You still handle store signing, push notifications, deep links, permissions, and platform-specific bugs. Cross-platform reduces duplicate business logic and UI work. It does not remove platform work entirely.

React Native (and Expo)

What it is: A JavaScript/TypeScript framework from Meta. Your UI is built with React components. React Native maps many of those components to real iOS and Android controls through a bridge (the architecture keeps evolving toward the New Architecture and more direct native paths).

Expo sits on top: tooling, build service, over-the-air updates, and a curated set of native modules. Many teams start with Expo and only "eject" or use custom dev clients when they need native code Expo does not ship.

Best for:

  • Teams already strong in React and TypeScript
  • Consumer and B2B mobile apps where native look-and-feel is important
  • Products that may also share logic with a React web app

Watch out for:

  • Native modules when you need NFC, Bluetooth quirks, or bleeding-edge OS APIs (custom native code or a config plugin)
  • Bridge performance on very animation-heavy UIs (often fixable, but not free)
  • Dependency churn when OS versions move

Real-world fit: I have shipped React Native with NFC for campus wallet style apps. That kind of hardware-adjacent feature is doable, but you plan for native modules and device testing early, not at the end.

Typical stack: React Native or Expo, TypeScript, React Navigation, often Firebase or Supabase for auth and data.

Flutter

What it is: Google's UI toolkit. You write Dart. Flutter draws its own pixels with the Skia engine instead of wrapping the platform's default buttons and lists.

Best for:

  • Greenfield mobile apps where you want one team and one language
  • Custom UI and motion (you are not fighting platform widget defaults as much)
  • Consistent look across Android and iOS from day one

Watch out for:

  • Hiring: fewer Dart developers than JavaScript developers in many markets (South Africa included)
  • Large app binary size compared to some native or thin-wrapper apps
  • Web and desktop targets exist, but mobile is still the main story for most products

Typical stack: Dart, Flutter SDK, Provider/Riverpod/Bloc for state, Firebase or REST backends.

React Native vs Flutter (short version): Choose React Native when your people and your web stack are already React. Choose Flutter when you want a single strongly opinionated UI layer and you are fine standardizing on Dart.

Ionic and Capacitor

What it is: Ionic is a UI component library built for web technologies (historically Angular-friendly, now works with React and Vue too). Capacitor (from the Ionic team) is the modern successor to Cordova: it wraps your web app in a native container and exposes native APIs through plugins.

Your app is largely a WebView plus native plugins for camera, filesystem, push, and so on.

Best for:

  • Teams that already have a responsive web app and want store presence quickly
  • Internal tools, content-heavy apps, forms, dashboards on mobile
  • MVPs where time to shelf matters more than maximum native polish

Watch out for:

  • Scroll, keyboard, and gesture feel can lag behind true native or Flutter/RN if the UI is complex
  • Heavy lists, maps, and games are usually the wrong fit
  • Plugin quality varies; you verify critical native features on real devices

Cordova still exists in legacy projects. New work should default to Capacitor, not Cordova.

Electron (and Tauri for contrast)

What it is: Electron packages a Chromium browser and Node.js with your front end (HTML, CSS, JavaScript). Desktop apps like VS Code, Slack, and many internal tools use it.

Best for:

  • Desktop apps for Windows, macOS, and Linux
  • Developer tools, kiosks, admin panels that need filesystem and OS integration
  • Teams that want the same web skills as their admin dashboard

Watch out for:

  • RAM and disk footprint (you are shipping a browser)
  • Security: Node in the renderer is dangerous if misconfigured; follow current hardening guidance
  • Auto-update and code signing on each desktop platform

Tauri is worth a mention: Rust backend, system WebView instead of bundled Chromium. Smaller binaries, steeper native/Rust learning curve. Good when Electron's size is a dealbreaker.

Electron is not a mobile framework. Do not use it for iOS/Android store apps in the normal case.

Other names you will hear

ToolRole
.NET MAUIMicrosoft's cross-platform UI for mobile and desktop from C#/.NET shops
Kotlin Multiplatform (KMP)Share business logic in Kotlin; UI often still native or Compose Multiplatform
Progressive Web App (PWA)Web app installable from the browser; limited store presence and OS integration
Native (Swift + Kotlin)Two codebases, maximum control, highest cost for small teams

KMP is strong when you want shared logic but native UI. That is a different bet than Flutter or React Native, where one UI codebase is the point.

Comparison at a glance

React NativeFlutterIonic/CapacitorElectron
Primary targetsiOS, Android (+ web experiments)iOS, Android, web/desktopiOS, Android (web app inside)Windows, macOS, Linux
LanguageJS/TSDartJS/TSJS/TS
UI modelNative components (mostly)Custom drawn UIWeb in WebViewWeb in Chromium
Reuse from web appModerate (React skills)LowHighHigh (often same SPA)
Store-ready feelStrongStrongDepends on UI complexityN/A (desktop)
Native/hardware APIsGood with modulesGood with pluginsPlugin-dependentOS APIs via Node/native

How I choose for a new project

Ask these in order:

  1. Which platforms are required? Mobile only, desktop only, mobile + web, all three?
  2. What does the UI need? Forms and feeds are forgiving. Maps, NFC, AR, games, and heavy animation narrow the list fast.
  3. What does the team already know? A mediocre React Native app ships faster than a first Flutter app built by JS developers learning Dart under deadline.
  4. What is the maintenance horizon? Cross-platform wins over years of duplicate native teams. It loses when you picked a WebView stack for a product that needed native performance from v1.
  5. What is the offline and device story? Storage, background sync, and peripherals push you toward RN/Flutter with real native modules, not a thin WebView wrapper.

Rule of thumb:

  • Mobile app, product quality bar: React Native or Flutter
  • We already have a great web app: Capacitor/Ionic first, validate UX on devices
  • Desktop tool for internal or power users: Electron or Tauri
  • Maximum control, budget for two teams: Native Swift + Kotlin

South African context

Most consumer traffic here is Android-first. Test on mid-range devices and slower networks, not only flagship iPhones on office Wi-Fi.

Data cost still matters. Bloated binaries and uncached images hurt real users. Cross-platform does not remove that responsibility.

Payment and identity integrations (Paystack, Ozow, local KYC flows) work on all major stacks, but you confirm WebView vs in-app browser vs native SDK behavior per provider before you commit to Ionic.

If you need a scoped build with honest stack advice, the engineering site covers mobile app development in South Africa. For a personal take or smaller advisory scope, get a quote.

FAQ

Is React Native still worth it in 2026?

Yes, for teams invested in React and for many production apps in the store. Evaluate Expo's constraints against your native module needs before you start.

Can one Flutter app replace our website?

Sometimes for simple cases. Most products still want a proper web property for SEO, sharing, and admin. Flutter web is an option, not a default.

Is Ionic "bad"?

No. It is misapplied when people expect native-game performance from a wrapped web app. Used for the right product, it is fast to ship and cheap to maintain.

Electron vs Tauri?

Electron is the safe default for teams that know Node and need mature ecosystem support. Tauri is worth a pilot when install size and memory matter.

Do cross-platform apps get rejected from the App Store?

Not for being cross-platform. They get rejected for broken UX, privacy violations, or WebView shells that feel like non-functional websites.

Where to go next

Cross-platform is a budget and team decision first, a framework decision second. Match the library to the product shape, then commit long enough to learn its failure modes.

Comments