You have a web app that works. Now someone asks: "Is there a mobile app?" and you realize the answer should be yes. The good news is that AI coding tools have made the jump from web to mobile dramatically faster. The bad news is that there are still real decisions to make, and picking the wrong path can cost you weeks.
This guide walks through your options, from the easiest possible path to a full native app on the App Store.
PWA vs React Native vs Flutter: Choosing Your Path
Before you write a single line of code, you need to pick an approach. Here is the honest breakdown.
Progressive Web App (PWA) is your web app with a few extras: a manifest file, a service worker, and responsive design. Users can "install" it to their home screen. It works on both iOS and Android. The upside is that you ship instantly with no app store review. The downside is that iOS limits what PWAs can do — no push notifications until recently, no background sync, and the experience still feels slightly off compared to a native app.
React Native with Expo gives you actual native apps for iOS and Android from a single JavaScript/TypeScript codebase. You get real native UI components, push notifications, camera access, and a presence in the App Store. The tradeoff is more complexity: you need Xcode, Android Studio (eventually), and an Apple Developer account.
Flutter uses Dart instead of JavaScript and gives you pixel-perfect control over every screen. It is excellent for custom UI-heavy apps. But if your team already thinks in React and TypeScript, the context switch to Dart adds friction that AI tools cannot fully smooth over.
The rule of thumb: If your app is mostly content and forms, start with a PWA. If you need native device features or app store distribution, go with React Native and Expo. Choose Flutter only if you have specific UI requirements that justify learning a new language.
The Fastest Path: PWA with Lovable
If you built your app with Lovable or any other AI web builder, turning it into a PWA is the lowest-effort option.
Step 1: Make it responsive. Open your app in Lovable and prompt it to make every page work on a 375px-wide screen. Check navigation, forms, and any data tables. Lovable handles Tailwind responsive classes well, so prompts like "make this layout stack vertically on mobile" usually work on the first try.
Step 2: Add a web app manifest. Create a manifest.json in your public folder with your app name, icons, theme color, and "display": "standalone". This tells the browser your site can behave like an app. You will need icons at 192x192 and 512x512 pixels minimum.
Step 3: Add a service worker. If you are on Next.js, the next-pwa package handles this automatically. For other setups, a basic service worker that caches your app shell is enough to pass the installability check.
Step 4: Test the install flow. On Android Chrome, you will see an "Add to Home Screen" prompt. On iOS Safari, users tap Share then "Add to Home Screen." Test both. The app should launch without the browser chrome.
That is genuinely it. You can go from web app to installable PWA in an afternoon. The limitation is that you are still running in a browser sandbox, so some features are off the table.
The Native Path: Cursor + Expo + React Native
When you need the real thing, this is the stack that works best with AI coding tools.
Initialize the project. Run npx create-expo-app@latest my-app and open the project in Cursor. Expo gives you a managed workflow where you rarely need to touch native code directly. You get hot reloading on your phone using the Expo Go app, which means you can iterate almost as fast as on web.
Scaffold screens with Cursor. This is where AI shines. Describe your screens in plain English: "Create a tab navigator with Home, Search, and Profile tabs. The Home screen should show a scrollable list of cards with an image, title, and subtitle." Cursor handles React Navigation setup, component structure, and basic styling. You will need to guide it on navigation patterns — mobile apps use stack navigators and tab bars, not the URL-based routing you are used to from web.
Handle platform differences. iOS and Android have different conventions. iOS uses large titles and swipe-back navigation. Android uses a top app bar and a hardware back button. Cursor knows these patterns, but you need to ask for them explicitly. Prompt for "platform-specific UI" and review what it generates on both platforms.
Connect to your backend. If your web app already has an API, your React Native app can call the same endpoints. Use fetch or a library like axios. For authentication, store tokens with expo-secure-store instead of localStorage. This is a common mistake — Cursor will sometimes suggest AsyncStorage, which is not secure for tokens.
Getting to TestFlight and Google Play
This is where most AI-built apps stall. The build and submission process is real work.
Apple (TestFlight). You need an Apple Developer account at 99 dollars per year. Use Expo EAS Build to create your iOS binary in the cloud — no Mac required for the build itself, though you will need one for certain debugging scenarios. Run eas build --platform ios and follow the prompts. Once the build finishes, submit it to TestFlight with eas submit --platform ios. Your first submission will take a day or two for Apple to process.
Google Play Console. The developer account is a one-time 25-dollar fee. Run eas build --platform android to get an AAB file. Upload it to the Google Play Console, fill in the store listing, and submit for review. Google's review is typically faster than Apple's.
App Store Review pitfalls. Apple rejects apps for surprisingly specific reasons. The most common: your app is "just a website in a wrapper" (they can tell), you are missing a privacy policy, your login flow does not include Sign in with Apple, or your app crashes on their test devices. Address these before submitting. Cursor can help you implement Sign in with Apple using expo-apple-authentication.
Common Pitfalls
Navigation patterns. The single biggest source of bugs in AI-generated mobile code is navigation. Web developers think in pages and URLs. Mobile apps think in stacks and modals. When you prompt Cursor, be specific: "use a stack navigator for this flow" or "present this as a modal, not a push."
Platform-specific UI. A button that looks fine on iOS can feel wrong on Android, and vice versa. Use platform-specific components where it matters. React Native's Platform.select lets you branch styles per OS.
Performance. Long flat lists need FlatList, not ScrollView with mapped components. AI tools often generate the naive version. If your list has more than 50 items, explicitly ask for FlatList with proper key extraction.
Over-relying on Expo Go. The Expo Go app is great for development, but it does not support all native modules. When you add a library that requires custom native code, you need to switch to a development build. Run eas build --profile development to create one.
Tools That Accelerate the Process
Expo EAS handles builds, submissions, and over-the-air updates. It removes the need to maintain local Xcode and Android Studio configurations for most tasks.
Capacitor is an alternative from the Ionic team. It wraps your existing web app in a native shell and gives you access to native APIs through plugins. If you have a polished PWA and want to get it into the app store without rewriting in React Native, Capacitor is the bridge. The tradeoff is that performance-intensive screens will still feel like a web view.
Expo Router brings file-based routing (like Next.js) to React Native. If you are coming from a Next.js background, this will feel familiar and reduces the navigation learning curve significantly.
The Practical Sequence
If you are starting from zero, here is the order that saves the most time:
You do not need to go native on day one. Start with the web, prove the demand, and upgrade when it matters.