How do you get your web app into the App Store and Play Store?

Wrap it in a thin native shell that loads your existing web screens, add native navigation so it does
not feel like a browser, and wire up in-app purchases because both stores require them for digital
goods. You maintain one codebase and ship to three places. The costs are **$99 per year** for Apple,
**$25 once** for Google, and **up to 30%** of every purchase made inside the app, which is usually
the number that decides whether this is worth doing at all.

## The approach

You do not rebuild your product twice. You build a small native application whose main job is to
display your web screens, plus the parts that genuinely have to be native.

That is not the same as shipping a bare browser window. A shell like this gives you:

- **Native navigation.** Screens push and pop with the platform's own transitions and gestures, which
  is most of what makes an app feel like an app.
- **Native controls where they matter.** Tab bars, the system share sheet, the camera, notifications.
- **Rules about which screens behave how**, served from your server, so you can change navigation
  behavior without shipping a new build through review.

That last point is worth dwelling on. Anything driven by your server changes when you deploy.
Anything compiled into the app waits for review. Keeping as much as possible on the server side is
the difference between a two-hour fix and a two-day one.

## What has to be native

Be realistic about the boundary:

- **In-app purchases.** Required. Not optional. More below.
- **Push notifications.**
- **Anything using hardware**: camera, location, biometrics.
- **The launch screen and icon.**

Everything else can be a web screen, and should be, because it is one implementation instead of
three.

## The in-app purchase rule, which decides your economics

If you sell digital goods or subscriptions that are used inside your app, both stores require you to
sell them through their purchase system, and both take a cut of up to 30%, reduced for smaller
developers under their respective programs.

You cannot avoid this by linking out to your own checkout from inside the app. That gets rejected,
and the rules around what you may and may not say about outside payment options have shifted
repeatedly. Read the current guidelines rather than a blog post, including this one.

The strategic consequence: **your web checkout and your in-app checkout are different businesses**
with different margins. Many products deliberately steer signups to the web, where they keep the full
amount, and treat in-app purchase as a convenience for people who found them in the store.

## The part that gets architecturally messy

You now have two ways for someone to pay, and they arrive as completely different things: a payment
provider's webhook on one side, and a store receipt on the other.

The trap is building two parallel systems that each track what a customer has paid for, and then
discovering they disagree. Somebody subscribes on the web and opens the app, which does not know. Or
subscribes in the app and uses the web, which does not know.

The fix is to make **entitlement a single concept**. One record per account answering "is this
account currently allowed to use the paid feature, and until when". Both payment paths write to it.
Everything else reads it and does not care where the money came from.

Get that right and adding a third payment route later is a small job. Get it wrong and every new
route multiplies the states you have to reconcile.

## What review actually catches

Both stores review submissions. The rejections that come up repeatedly:

- **Looking too much like a website.** If it is visibly a browser window with your site in it, expect
  a rejection. Native navigation is the main thing that fixes this.
- **Payment rules.** Any route to paying that is not their route.
- **Sign in with Apple.** If you offer other social sign-in options on iOS, you are generally required
  to offer Apple's too.
- **Account deletion.** If someone can create an account in the app, they must be able to delete it
  from the app. Not by emailing support.
- **Broken or unreachable screens.** Reviewers do click things.
- **Privacy disclosures** that do not match what the app actually collects.

Most of these are cheap if you know them in advance and expensive if you find them at submission,
because each round trip through review costs days.

## The realistic timeline

For a product whose web app already exists and works:

| Work | Time |
|---|---|
| Shell running, loading your screens | 1 to 2 days |
| Native navigation rules | 1 to 3 days |
| In-app purchase, both platforms | 3 to 7 days |
| Icons, launch screens, store listings, screenshots | 2 to 3 days |
| Review, first submission | 1 to 7 days, plus rework |

Call it two to three weeks including the first rejection, which you should assume rather than hope
against.

The in-app purchase line is the one that surprises people. It is not just a payment button, it is
receipt validation, restoring purchases, renewals, and the notifications that tell your server when a
subscription changed state. It is the same [source-of-truth problem as web
payments](/blog/charging-for-your-app), in a different shape.

## Is it worth it?

The honest answer is that it depends on where your customers look for you.

**Probably yes** if your product is used on a phone regularly, if being findable in a store matters
to your audience, or if you need notifications or hardware access.

**Probably not yet** if your product is used at a desk, if your customers find you through search or
word of mouth, or if you have not validated the web version. Two to three weeks plus 30% of in-app
revenue is a real price for a channel that may not be where your customers are.

If you do go ahead, get the entitlement model right first. That single decision determines whether
the second payment route is a week of work or a permanent source of support tickets.
