Iskhak AsanovOpen to roles

Rebuilding mobile: From a web app in a shell to native

Our clients use the product on their phones, mid-task. I replaced our Capacitor web wrapper with a native Expo/React Native app under the same store ID.

Where we started

I started with a responsive web app wrapped in Capacitor: one codebase, one team, faster releases. We invested heavily in making web screens feel native, with safe areas, bottom sheets, haptics and push notifications.

The problem

Every native detail was a fight with the web layer; we even had to restore the iOS webview pan after the keyboard closed.

The rebuild

In September 2026 I rebuilt the app natively. The first design rule in its project file is “Do not port web decisions”:

  • iOS gets Liquid Glass on iOS 26, with a fallback below it
  • Real native controls (SwiftUI on iOS, Jetpack Compose on Android) instead of React views styled to look native
  • Every list virtualized, every destructive action a native confirm, every finger-driven state change gets haptics
  • Gestures and transitions on the UI thread with Reanimated worklets

Outcome

It shares the same Supabase backend, the same RLS authorization and the same query-key vocabulary as the web app, and it shipped under the existing store ID, so users simply updated.

What I’d do differently

Decide the mobile approach from how users actually work, before writing the first screen.