From web app to store-ready source
A practical guide for turning a website or PWA into a native project Shiptavio can build and submit. It covers the route choices, the native work, the files to send, and the cases where this service is not a fit.
Shiptavio does not do these steps for you
This guide helps you arrive with a project we can build. We do not choose the framework, rewrite the UI, or generate the native project from your website.
Check the fit before you convert
Not every web app should become a store app through this service. The conversion is a real project, so check the boundaries first.
A good fit
- The app is free, with no in-app purchases or subscriptions.
- It is not in a prohibited category.
- Every API it calls is production HTTPS, with no localhost or private LAN addresses.
- You own the code, name, logo, and content.
- You can provide a working demo account if the app has a login.
- You can add in-app account deletion if users can create an account.
Not a fit
- A paid app, in-app purchases, or digital subscriptions.
- Gambling, crypto, finance, medical, VPN, adult, or government apps.
- An app that only works against localhost or a private LAN.
- An app you do not have the rights to publish.
- A finished .ipa or .aab without readable source.
- A no-code tool that cannot export a native project.
If your web app sells digital goods, stop here
Apple's rules generally require In-App Purchase for digital content and subscriptions sold inside an app. We do not support in-app purchases. Wrapping a Stripe checkout in a WebView is not a workaround, and it is a common rejection reason.
Read the prohibited apps list before you start.
Pick a conversion route
Choose based on how much of the web UI you want to keep. The commands below are a starting point, not a complete migration.
Capacitor
Wrap your existing web build in a native shell.
- Best for
- A responsive web app that needs to reach both stores without a UI rewrite.
- Platforms
- iOS and Android. The iOS platform needs macOS and Xcode; Android needs Android Studio.
- You reuse
- Your HTML, CSS, JavaScript, and most of your screens.
- You rewrite
- Native navigation, permissions, and anything that depends on a desktop browser.
npm install @capacitor/core @capacitor/cli
npx cap init "Your App" com.yourcompany.yourapp --web-dir distnpm run build
npx cap add ios
npx cap add android
npx cap syncDo not point the WebView at your live website with server.url. Bundle the web build into the app. Apple rejects thin wrappers that add no native value.
What to send us
The project root, including ios/ and android/, capacitor.config.ts, your lockfile, and the command that builds the web assets.
TWA and Bubblewrap can put a PWA on Google Play, but they do not give you an iOS app. A PWA is a web app, not a native app. If you need both stores, use one of the routes above.
Prepare the app for a native shell
A web app that works in a browser can still fail inside a native shell. Fix these before you generate the native project.
Layout and navigation
- Respect safe areas and the on-screen keyboard.
- Support the Android back button and the iOS back gesture.
- Remove hover-only interactions or add a tap equivalent.
- Keep tap targets at least 44 x 44 px.
- Test small screens, large screens, and text zoom.
Native behavior
- Add a real offline and error state instead of a blank screen.
- Request permissions at the moment of use, not at launch.
- Add deep links or universal links if the app uses URLs.
- Use a plugin or native module for camera, files, and push.
- Test OAuth and cookie login inside the shell.
Account and data
- Point every API at production HTTPS.
- Provide a working demo account for store review.
- Add in-app account deletion if users can create an account.
- Add a privacy policy that matches what the app collects.
- Remove test data and test credentials from the build.
Do not ship a remote URL wrapper
Bundle the web build into the app. A WebView that loads your live website adds no native value, breaks when the site is down, and is a known rejection risk under Apple Guideline 4.2.
Generate and configure the native project
The route picker shows the commands. This step covers the identity and configuration that are easy to get wrong.
import type { CapacitorConfig } from "@capacitor/cli";
const config: CapacitorConfig = {
appId: "com.yourcompany.yourapp",
appName: "Your App",
webDir: "dist",
// Do not add server: { url: "https://..." } here.
};
export default config;Identity
- Choose the bundle ID and Android package name once.
- Set the app name and a clear version number.
- Add the app icon and splash screen.
- Add the URL scheme and universal links if needed.
- Keep the identifier stable after the first publish.
Permissions and environment
- Add an iOS usage description for every permission.
- Add Android permissions to the manifest.
- Keep environment variables on production URLs.
- Do not commit .env files, keystores, or private keys.
- Document any extra build step in the build notes.
In the registration form, pick Expo, React Native, or Flutter if that is what you used. Pick Other for a Capacitor or fully native project.
Test on real devices
A simulator is not enough for a store build. Test on at least one real device for each platform you target. If you target both stores, use one real iPhone and one real Android phone.
iPhone
- First launch, sign in, and the core task.
- Safe areas, keyboard, and back swipe.
- Camera, files, notifications, and permission denial.
- Offline mode and a failed request.
- Rotation if the app supports it.
Android
- First launch, sign in, and the core task.
- Back button and back gesture.
- Keyboard, permissions, and notification behavior.
- Offline mode and a failed request.
- Small and large screens, including a tablet if supported.
What store reviewers will try
They may open the app, sign in with the demo account, use the main flow, deny a permission, and look for account deletion. If a step does not work, say so in the review notes instead of claiming it does.
Package the source and assets
This is what we need. Source first, then the store assets and details.
Source tree
A Capacitor project should look roughly like this. Expo and Flutter have their own layouts, but the same rule applies: include the native projects or the command that generates them.
my-app/
package.json
pnpm-lock.yaml
capacitor.config.ts
ios/
App/
Podfile
android/
app/
build.gradle
src/
public/
README.mdLeave out
- node_modules/ and other dependency folders.
- .git/ and editor settings.
- Build output such as dist/, build/, or .next/.
- .env and .env.* files.
- Keystores, .p12 files, and provisioning profiles.
- Test data and test credentials.
Package tracked files
Commit the native folders first, then archive the tracked files. This follows your .gitignore and keeps build output out of the zip.
git add ios android
git commit -m "Add native projects"
git archive --format=zip -o my-app-source.zip HEADThe zip limit is 200 MB. If you use the Shiptavio CLI after signing up, it follows your .gitignore and leaves out .env files and private keys automatically.
Store assets
These are the sizes the stores enforce. Use real screenshots from the app, not mockups of a website.
iOS app icon
1024 x 1024 px
PNG or JPEG, no transparency
Android app icon
512 x 512 px
PNG or JPEG
Android feature graphic
1024 x 500 px
PNG or JPEG
iPhone screenshot
1179 x 2556, 1206 x 2622, or 1320 x 2868
Portrait or landscape
iPad screenshot
2064 x 2752 or 2048 x 2732
Required if the app runs on iPad
Android screenshot
1080 x 1920 recommended
320 to 3840 px per side
Full asset list, including macOS, tvOS, and visionOS
| Asset | Platform | Required size |
|---|---|---|
| App icon | iOS | Exactly 1024 x 1024 |
| App icon | Android | Exactly 512 x 512 |
| Feature graphic | Android | Exactly 1024 x 500 |
| Screenshot | iOS, iPhone | 1179 x 2556, 1206 x 2622, or 1320 x 2868 |
| Screenshot | iOS, iPad | 2064 x 2752 or 2048 x 2732 |
| Screenshot | Android | 320 to 3840 px per side, long side at most 2x the short side |
| Screenshot | macOS | 1280 x 800, 1440 x 900, 2560 x 1600, or 2880 x 1800 |
| Screenshot | tvOS | 1920 x 1080 or 3840 x 2160 |
| Screenshot | visionOS | 3840 x 2160 |
| Product page header, optional | iOS | 3840 x 1646 (21:9) or 5244 x 2950 (16:9), no transparency |
| Search results asset, optional | iOS | 3:2 between 1920 x 1280 and 3840 x 2560, or 5244 x 2950, no transparency |
| App preview, optional | iOS | Up to 3 .mp4, .mov, or .m4v files, 200 MB each |
| Routing coverage, optional | iOS | GeoJSON .geojson or .json, up to 20 MB |
Accepted file types for images: PNG or JPEG only. Apple requires at least one iPhone screenshot. If the app runs on iPad, Apple also requires at least one iPad 13-inch screenshot.
Store text limits
| Field | Limit |
|---|---|
| Name or title | 30 characters |
| iOS subtitle | 30 characters |
| Android short description | 80 characters |
| Full description | 4000 characters |
| iOS keywords | 100 characters total |
| iOS promotional text | 170 characters |
What to send
Source
- GitHub URL or source zip (required).
- ios/ and android/ folders (required for wrappers).
- Lockfile and package manager (required).
- Exact build command (required).
- Environment variables (if the app uses them).
Assets
- App icons (required).
- iPhone and iPad screenshots (required for iOS).
- Android screenshots (required).
- Android feature graphic (required).
- App preview videos, product page header, routing coverage (optional).
Store text and access
- Name, subtitle or short description, full description (required).
- Keywords, categories, support email, privacy policy (required).
- Demo account for review (required if the app has login).
- Review contact (required) and reviewer notes (recommended).
- Marketing URL, promo video (optional).
Compliance
- Apple age rating and Google Play content rating (required).
- Privacy and data safety answers (required).
- Content rights and export compliance (required).
- Made for Kids and ads declaration (required).
- In-app account deletion (required if users can create an account).
No source, no build
If your tool only gives you a finished binary or locks the project inside its own hosting, we cannot build it. We need readable source and a native project.
Submit and publish
Once the source and assets are ready, the Shiptavio flow is short.
- 1Create an account and register the app.
- 2Choose the framework and the target platforms.
- 3Add the source, build command, and environment variables.
- 4Upload the assets and complete the store details and checklist.
- 5Pay for the term. We review, build, sign, and submit. You track the status in the dashboard.
What happens next
We review the source, run your build command, sign with our developer accounts, and submit to the stores you selected. Store review timing is controlled by Apple and Google. We cannot promise a date.
Updates
Your first publish uses one release credit. Each later update uses one more. Fixes to the same release do not use another credit. Check the pricing page for the current term and credit package.
Common questions
The answers that decide whether this route is worth starting.
Can I send a website or PWA and let Shiptavio convert it?
Do I need a Mac?
Will Apple accept a WebView wrapper?
Can I keep my Stripe subscriptions inside the app?
Which route should I choose?
What files do you need?
Can I use a no-code app builder?
Do you guarantee store approval?
Ready to send the project?
If the native project exists and the files are ready, register the app. If you are still choosing a route, go back to the overview.