Shipping an AI iOS App: The Stack We Actually Use
Shipping an AI iOS App: The Stack We Actually Use
We have shipped several AI apps to the App Store now. The stack has converged. Here it is, with honest notes about where it hurts.
The shape
- Expo / React Native for the app
- RevenueCat for subscriptions
- Firebase for auth and user data
- A thin serverless API in front of the model provider
- Native App Store distribution via EAS
Nothing exotic. That is deliberate — the interesting engineering should be in the retrieval and the domain content, not in re-solving authentication.
Why Expo
One codebase, fast iteration, and over-the-air updates for anything that is not native. For products where the differentiator is the AI and the domain knowledge rather than platform-specific interaction, the tradeoff is clearly worth it.
The honest cost: the moment you need a native module that is not in the ecosystem, you are doing a config plugin and a custom dev build, and you have lost the simplicity that sold you on it. Budget for that happening at least once per app.
Never put your model key in the app
This is the one non-negotiable. The app talks to your API, your API talks to the model provider. Ship a provider key in the bundle and it will be extracted.
Routing through your own endpoint also buys you the things you will want later anyway:
- Rate limiting per user
- Prompt and retrieval logic you can change without an app release
- Cost visibility
- The ability to switch model providers without shipping a build
That last point has already paid for itself more than once.
Subscriptions are harder than the AI
Nobody warns you about this. The AI integration is a few days. Subscriptions are weeks.
You are dealing with trial states, restore purchases, cross-device entitlement, sandbox behaviour that differs from production, and App Review asking pointed questions about your paywall. RevenueCat removes most of the server-side pain and none of the state-machine complexity.
Two things that saved us repeatedly:
- Entitlement checks in one place. A single source of truth for "is this user pro." Scatter that logic and you will ship a bug where a paying customer gets locked out.
- A path through the app that does not require a purchase to evaluate. Reviewers need it and so do real users deciding whether to trust you.
Offline is a feature, not a fallback
Our field apps are used in mechanical rooms, basements, and rooftops. Signal is unreliable.
The rule we settled on: anything deterministic works offline. All six calculators in our HVAC and electrical apps run entirely on-device. Only the AI assistant requires a connection, and it says so clearly rather than hanging.
This is the single most appreciated design decision in the products, and it never appears in a feature list.
What we would do differently
Start with the evaluation harness. We built domain evaluation after the first app was in review. Doing it first would have caught content problems earlier and cheaper.
Design the paywall before the features. Retrofitting entitlement boundaries onto a finished app is miserable.
Treat the corpus as the product. The app is a delivery mechanism. The reference material and how faithfully it is retrieved is what people are paying for.
If you are building something similar and want to compare notes, reach out.