Guide · for the person with a working web app, a repo, and users asking for the app
Convert a web app to a mobile app: the three routes, and what carries over in each
You built a web app. It works, the code is in a repository, people use it, and the next request is “is there an app?”. There are exactly three ways from here to the App Store and Google Play: put the web app inside a native shell, rebuild it as native apps by hand, or connect the repository to an agent that does the rebuild with a plan you approve. This page is for the founder or product person choosing between them: what each route keeps from your codebase, what it rebuilds, what it costs you in control, and the three questions that decide it.
Verified
What “convert” can mean. A web app is HTML, CSS and JavaScript that a browser renders, talking to a backend. A mobile app is a project that the phone runs — and “convert” means one of three different things: keeping the web app and wrapping it in a native shell so it can go in the stores; rebuilding the screens as native ones (SwiftUI on iPhone, Jetpack Compose on Android) that talk to the same backend; or the same rebuild with agents doing the work from your repository. The good news before the comparison: in every route, your backend, your data, your users and your business rules carry over. What differs is what happens to the screens and who owns the result.
How to choose: three questions
1. Is the phone app the same product as the website, or a different one? If users want the web app in their pocket with an icon and notifications, the wrapper is the shortest route. If the phone app has its own jobs — camera, offline, widgets, notifications that open the right screen, a subscription through the store — it is a different product and gets built as one.
2. Who will own the mobile code in a year? A wrapper’s project is a shell around web code; the product logic stays in the web app. A native rebuild gives you Swift and Kotlin projects an iOS or Android engineer can take over, or an acquirer can read. Code export vs no-code lock-in is the long version of this question.
3. Do you need Android at the same time? Most conversions do — a web product already serves both. A wrapper covers both from one web app; a by-hand rebuild is two apps; an agent rebuild from one project covers both if the tool writes the logic once. Ask how Android comes out before you pick.
The three routes, compared
The table shows what carries over from your repository in each route and what gets rebuilt. Rows are routes, not products; the tools that do each are named in the sections below.
| Route | Backend, data, users | Auth | Business rules | Screens | What runs on the phone | Both platforms | Projects you hold |
|---|---|---|---|---|---|---|---|
| 1. Wrap it (Capacitor / Despia) | Carry over | Carry over | Carry over (in the web code) | Carry over as web pages | Your web app in a WebView | Yes, one web app | A shell around the web app |
| 2. Native rebuild by hand | Carry over | Same provider, native SDKs | Re-implemented natively | Rebuilt in SwiftUI + Compose | Native UI | Two apps, two codebases | Xcode + Android Studio projects |
| 3. Modaal import from the repo | Carry over | Same provider, native SDKs | Written once, rendered on each platform | Rebuilt in SwiftUI + Compose from the plan | Native UI | Yes, from one project | Xcode + Android Studio projects on your disk, every plan |
Routes, not products. Guideline 4.2 applies to route 1. No durations are given for any route because they depend on the app.
1. Wrap it — best for “the website is the product, I want it in the stores”
What it is: your web app running inside a native WebView, packaged for the stores with Capacitor (do it yourself) or a service like Despia (which describes its own output as “your web code running in the platform WebView”), with a bridge so the web code can use push, camera and purchases. What carries over: everything — it is the same web app. What you accept: the app is still a web page; navigation, gestures and new device layouts are whatever the web app implements, and Apple’s guideline 4.2 sets the bar: “Your app should include features, content, and UI that elevate it beyond a repackaged website.” A wrapper that adds push, offline or camera clears it; a site in a frame is what the sentence is written for. Turn a website into an app has the full route and what has passed.
2. Rebuild it natively by hand — best for a product with its own phone jobs and a developer available
What it is: what a mobile developer does when you hand them your repository. They read the routes (each becomes a screen), the data model, the API calls and the auth provider; they rebuild the screens in SwiftUI for iPhone and Jetpack Compose for Android; they point both at the same backend. If the backend is Supabase, the iPhone app uses Supabase’s own Swift client and the Android app the community-maintained Kotlin one. What carries over: backend, data, users, auth, business rules, the API. What is rebuilt: every screen, the navigation, the state handling — twice, once per platform. What you accept: two codebases to maintain, and a brief you have to write well enough that the developer builds the app you meant. The brief is the same document as the one-page PRD: screens, what each must do, what is out. If your web app is React or Next.js, convert a React app to a native mobile app has the file-by-file view of what maps and what doesn’t.
3. Connect the repo to Modaal — best for the same result without hiring, on both platforms from one project
What it is: the by-hand route, done by agents, from your repository. You connect the GitHub repo; Modaal reads it the way a developer would — routes, screens, data model, API, auth — and writes a plan: the screen list, the features, what maps to what, as a document you approve before any code is written. Then the agents rebuild feature by feature: the logic once, the SwiftUI screens for iPhone, the Jetpack Compose screens for Android, against the backend your web app already uses. From Modaal’s documentation: “Each feature’s logic — its state, the actions that change it, the effects it requests — is written once,” and “The iPhone app renders that state in SwiftUI; the Android app renders it in Jetpack Compose.” You test each feature on a real phone as it lands; the Xcode and Android Studio projects are on your own disk from the first feature, on every plan. The web app keeps running untouched.
What carries over: the same as route 2 — backend, data, users, auth, business rules. What is rebuilt: the screens, natively, from the plan — the UI is re-created for the phone, not ported from CSS. What you accept: a Mac, and reading the plan instead of a one-line prompt. Price: Free for 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. The product page is /web-to-native; the import is rolling out to early-access users in October 2026, and the list is on that page.
Which should you use?
Website is the product, users want it on the home screen with notifications: wrap it, add the native features that make it more than the site in a frame, read 4.2 before submitting.
The phone app has its own jobs, you have a developer, and one platform is enough for now: rebuild by hand; write the PRD first so the developer builds what you meant.
The phone app has its own jobs, you want both platforms, and you'd rather approve a plan than hire: connect the repo to Modaal; the web app stays as the web product and the native apps ship from one project.
Not sure yet: the wrapper is reversible and the spec is portable. Ship the wrapper, watch what phone users do for a month, then rebuild from the spec if the phone becomes the product.
Frequently asked questions
Yes, in one of three ways: wrap the web app in a native shell (Capacitor or a service like Despia) so it can go in the stores; rebuild the screens natively by hand against the same backend; or connect the repository to Modaal, which reads it, writes a plan you approve, and rebuilds the screens in SwiftUI and Jetpack Compose from one project. In all three your backend, data and users carry over.
Not by translating the code. Web UI (HTML, CSS, browser APIs) has no native equivalent, so any native result is a rebuild of the screens. What can be automated is the rebuild itself: an agent reads the routes, data model, API and auth from the repository, proposes the screen list and features as a plan, and writes the native screens from it. That is what the Modaal import does; a developer does the same by hand.
A wrapper keeps the web app and runs it inside a native shell; one codebase, changes go live without a store update, and the app behaves like a web page. A native rebuild produces SwiftUI and Jetpack Compose screens that talk to the same backend; the app behaves like the phone’s own apps and follows platform updates first, at the cost of screens being built for each platform.
Apple’s guideline 4.2 requires an app to “include features, content, and UI that elevate it beyond a repackaged website.” A wrapper that adds push notifications, offline content, camera or native navigation is doing something the website does not; a site in a frame is what the guideline is written against. Turn a website into an app has the guideline text and what has passed.
Yes, in every route. The mobile app is a client; it talks to the API, database and auth provider your web app already uses. With Supabase, for example, the iPhone app uses Supabase’s own Swift client and the Android app the community-maintained Kotlin client. Users, data and business rules do not move.
For the wrapper route, a developer or a wrapper service. For a native rebuild by hand, yes. For the Modaal import, no: you connect the repository, approve the plan, and test each feature on a phone; the projects that come out open in Xcode and Android Studio, so a developer can join later.
A wrapper gives both from one web app. A by-hand rebuild is two apps. The Modaal import writes each feature’s logic once and renders it in SwiftUI on iPhone and Jetpack Compose on Android from one project, so both platforms come from the same plan.
Your own Apple Developer Program membership ($99 a year) and Google Play Console ($25 once), opened before the first build so the app is published under your account; the repository; the backend credentials; and a one-page list of the screens the phone app needs, which is the same document whether a developer or an agent does the work.
Connect the repo. Approve the plan. Ship both stores.
Modaal reads your web app’s repository, writes a plan you approve, and rebuilds it as native iOS and Android apps from one project — same backend, same data, your own AI agent. Free for one project.
Keep reading
- Web app to native mobile app
The import, step by step.
- Convert a React app to a native mobile app
What maps from React and Next.js, file by file.
- Turn a website into an app
The wrapper route and guideline 4.2 in full.
- Native vs cross-platform app
What runs inside the binary, defined.
- The PRD prompt
The brief a developer or an agent builds from.
- Convert an iOS app to Android
What carries over from an existing iOS app.