Guide · iOS and Android · with a worked example
The best way to create a mobile app for iOS and Android: 8 steps, with one example carried through all of them
Most guides list the steps and leave you to imagine what each one produces. This one takes a single small app, RunClub Check-in, from idea to the App Store and Google Play, and shows the actual artifact at every step: the validation signal, the one-page PRD, the stack decision, the screen list, the first feature plan, the build, the backend, and the two store submissions.
Verified
The example. A weekly running club checks members in at the start line from a paper list. The organiser wants a phone app instead: members tap once to check in, the organiser sees the list live, and next week's run takes a minute to set up. Members have iPhones and Android phones, so the app has to be on both. That is RunClub Check-in, and it is small on purpose: a first version should be.
The short answer, before the steps. The best way to create an app for iOS and Android today is to validate it cheaply first, write one page that says what it does, decide the stack once, and then build it feature by feature from one project that produces both native apps, with a plan approved before each feature. The eight steps below are that sentence, expanded, with RunClub at every step.
iOS and Android app development in 8 steps, at a glance
- Validate the idea before any app exists. 2. Write the one-page PRD. 3. Decide platforms and stack, once. 4. Design the screens with references. 5. Plan the first feature before any code. 6. Build feature by feature, both platforms from one project. 7. Set up the backend once, under your own account. 8. Test on both phones and publish to both stores. The table further down lists the artifact each step produces for RunClub and the page that covers the method in depth.
Step 1. Validate the idea before any app exists
What you do. Find out whether the problem is real and whether the people who have it would change what they do. Talk to the people with the problem, watch the current workaround, and define one signal you will check after launch. A web prototype or a landing page is enough at this stage; no store account is needed yet. How to test your app idea before you build has the method.
RunClub. The workaround is the paper list. The organiser is the one who decides whether the app replaces it, so the signal is about the organiser, not about downloads: the organiser does not bring the paper list on week three.
Produces: the one-sentence job and the success signal.
Step 2. Write the one-page PRD
What you do. One page: who uses it and in which moment, the job, three core flows, what the first version leaves out, how you will know it works, what must never break, and the platforms. The PRD prompt writes it from six questions; the app requirements document template has the full RunClub PRD.
RunClub. The moment: the thirty seconds before the run, cold hands, unreliable signal. Three flows: member taps once to check in; organiser sees the list live; organiser creates next week's run. Left out of v1: accounts and passwords, payments, route maps, push notifications, history, any admin website. Must never break: check-in works offline and syncs later; no account needed for members; members see only first names.
Produces: PRD.md, one page.
Step 3. Decide platforms and stack, once
What you do. Decide two things you cannot cheaply change later. Which platforms: iPhone only, iPhone now and Android later, or both from the start. And which stack: a web app in a native shell (Capacitor or a service like Despia), a cross-platform framework (React Native or Flutter), or native, SwiftUI on iPhone and Jetpack Compose on Android. Switching stack later is a rewrite. Native vs cross-platform has the trade-offs in full.
RunClub. Members carry both kinds of phone, the check-in has to work offline in the cold, and the tap has to feel instant: that points to native on both. Because Android is planned within the season, the project is set up for both platforms from the first day, even if iPhone ships first. Adding Android to an iPhone-only codebase later is the expensive version of the same decision.
Produces: one line in the PRD: native, iPhone and Android from one project.
Step 4. Design the screens with references
What you do. List every screen from the three flows, then find a reference for each in real apps rather than starting from a blank canvas. Libraries of real app screens such as Mobbin show how shipped apps solve the same screen on iOS and Android (design reference tools compared). If a designer works in Figma, an agent can read the file (Figma to SwiftUI and Jetpack Compose).
RunClub. Four screens: this week's run (name, date, one large check-in button), checked in (confirmation that works without signal), organiser's live list (first names, count), create run (name, date, time). The reference that matters most is the check-in button: large enough for cold fingers, with a state that shows "saved, will sync" when there is no signal. That state is in the PRD's must-never-break list, so it gets a design, not an afterthought.
Produces: a picture or reference for every screen, and the states the design must show.
Step 5. Plan the first feature before any code
What you do. Take the first core flow and write its plan: an overview, the user scenarios as Given/When/Then (one per ending, including the failures), the technical approach, the steps, the risks, and one test per scenario. Read it and change it before anything is built. In Modaal this is Plan mode: the first turn writes PRD.md and the first feature's spec to specs/001-<feature>/spec.md without writing code, and you approve it. With any other agent, ask for the same document explicitly. PRD to app walks this step in detail.
RunClub, feature 001, Member check-in. Scenarios: checks in with signal; checks in with no signal (saved locally, synced later); taps twice (one check-in, not two); the run was cancelled. Risks written down before the build: two clubs sharing a code; the same name checking in from two phones while offline. One test per scenario; the no-signal one run with networking switched off.
Produces: spec 001, approved.
Step 6. Build feature by feature: the logic once, the screens twice
What you do. Build one feature at a time from its approved plan, run it, compare it to the design, and correct it in sentences. For iOS and Android from one project, the structure matters most: each feature's logic (its state, the actions that change it, the effects it requests) is written once, and each platform renders it with its own native screens, SwiftUI on iPhone and Jetpack Compose on Android. That is how Modaal's Duet templates work; how to build a cross-platform mobile app with AI covers the method, including how the build proves both apps behave the same and where they should differ on purpose.
RunClub. Feature 001 is written once: the check-in writes locally first, then to the shared list, with a retry. The iPhone screen and the Android screen are built from each platform's own parts, so the check-in button follows each system's conventions. Then feature 002 (organiser's live list, which reuses 001's shared list) and 003 (create run), each with its own plan.
Produces: a running app on both platforms after each feature, not at the end.
Step 7. Set up the backend once, under your own account
What you do. Pick one hosted backend (Firebase or Supabase are the usual choices), create it in your own account, set the rules for who can read and write what, and keep the keys out of the agent's chat and out of the repository. Vibe coding and API keys has the four rules and the one prompt to send first. Both apps talk to the same backend; users and data are shared.
RunClub. One table of runs, one of check-ins. Rules: anyone with the club code can add their own check-in and read first names for this week's run; only the organiser can create runs. Offline check-ins sync when the phone is back online, and the duplicate-name risk from step 5 is handled here, in one place for both apps.
Produces: a backend you own, with rules written down, shared by both apps.
Step 8. Test on both phones and publish to both stores
What you do. Test on real devices, both kinds, in the conditions from the PRD; then open both store accounts and submit. Two things catch first-time publishers on Android and iOS:
Open both accounts in week one. The Apple Developer Program is $99 a year; Google Play Console is $25 once. On Google Play, new personal accounts must "run a closed test for their app with a minimum of 12 testers who have been opted in continuously for at least 14 days" before they can request production access. Start that closed test as soon as the first feature runs on Android, not when the app is finished.
Test the states, not only the happy path. Simulators show one state at a time; on iPhone the default tooling does not let an agent rotate or fold the device on its own (how AI agents test iPhone apps). Use real phones for the conditions that matter, and read App Store rejection reasons before the first submission.
RunClub. The test that matters is the start line: airplane mode on, cold-hands tap, check-in saved, signal back, list updated on the organiser's phone. Five members on iPhone through TestFlight; the twelve-tester closed test on Google Play with club members on Android, running in parallel. Then both submissions.
Produces: the app in review on both stores, under your own accounts.
Which tools fit each step
Steps 1–2: any chat model for the PRD; a web builder such as Lovable or Bolt if you validate with a web prototype. Step 3: a decision, not a tool. Step 4: a reference library, Figma if a designer is involved. Steps 5–6: the stack decides the tool. For native iOS and Android from one project with the plan step built in, Modaal runs on the Claude, Cursor or Codex subscription you already pay for, with the Xcode and Android Studio projects on your disk; the Free plan covers one project with unlimited prompts on one platform, Pro is €9 per user per month billed annually (€15 monthly) and adds both platforms, TestFlight distribution and Git collaboration (/pricing). Claude Code or Cursor on their own work too, with the plan, the structure and the tests as your responsibility. Step 7: Firebase or Supabase. Step 8: Xcode and App Store Connect, Android Studio and Play Console.
The 8 steps, the RunClub artifact, and where to go deeper
| Step | What you do | RunClub artifact | Deep page |
|---|---|---|---|
| 1. Validate | Check the problem and define one signal | “Organiser leaves the paper list at home by week three” | Test your app idea before you build |
| 2. PRD | One page: moment, job, three flows, cut list, constraints | PRD.md with offline check-in as a must-never-break | App requirements document template |
| 3. Stack | Platforms and stack, decided once | Native, iPhone and Android from one project | Native vs cross-platform |
| 4. Design | Every screen from the flows, with references | Four screens, incl. “saved, will sync” state | Design reference tools |
| 5. Plan | Scenarios and risks before code | spec 001 Member check-in, four scenarios | PRD to app |
| 6. Build | One feature at a time; logic once, screens twice | 001 → 002 → 003, running on both after each | Build a cross-platform app with AI |
| 7. Backend | One backend in your account, rules, keys out of chat | Runs and check-ins tables; code-based rules | Vibe coding and API keys |
| 8. Publish | Both phones, both stores, accounts in week one | TestFlight + 12-tester closed test in parallel | App Store rejection reasons |
RunClub Check-in is an illustrative example app. Store requirements quoted from Apple and Google, read 3 October 2026.
Frequently asked questions
Validate the idea cheaply, write a one-page PRD, decide the stack once, then build feature by feature from one project that produces both apps, approving a plan before each feature. For native apps on both platforms, that means each feature’s logic is written once and rendered in SwiftUI on iPhone and Jetpack Compose on Android.
Yes, three ways: a web app in a native shell (the same web page on both), a cross-platform framework such as React Native or Flutter (one codebase, the same UI on both), or native apps from one project (shared logic, each platform’s own screens). They differ in what runs inside the app, not in whether it reaches both stores.
Launch where your users are, but set the project up for both from day one if the second platform is planned. Adding Android to an iPhone-only codebase later costs more than choosing a structure that produces both. On Google Play, start the 12-tester, 14-day closed test early either way.
The Apple Developer Program is $99 a year and Google Play Console is $25 once. Those fees are the same whichever tool you build with. New personal Google Play accounts also need a closed test with at least 12 testers opted in for at least 14 days before production access.
No. With an AI agent, the code is written for you; your work is the PRD, the stack decision, the screen references, approving each feature’s plan and testing on real phones. Someone who writes code can work faster in the same steps; the steps do not change.
It is an illustrative example we use across our guides to show real artifacts at each step: the PRD, the feature spec, the screens, the backend rules. It is not a customer story, and this page claims no users or results for it.
Because the plan is where the scenarios and the risks get written down: no signal, a double tap, a cancelled run. An agent builds what the plan says. Without the plan, the failure cases appear in testing or in production, and every new feature is more likely to break an earlier one.
Write the PRD. Approve the plan. Ship iOS and Android from one project.
Modaal takes your one-page PRD, writes the feature plan you approve, and builds native SwiftUI and Jetpack Compose apps from one project, with your own AI agent. Free for one project.
Keep reading
- App requirements document template
The full RunClub PRD and feature spec.
- How to build a cross-platform mobile app with AI
Step 6 in depth: logic once, screens twice, parity in the build.
- How to make an app: seven decisions
The decisions behind the steps.
- Native vs cross-platform
Step 3 in full.