Skip to content
NEW v0.2.0 — Tracks, roadmaps and tiered stacks
STACK IT FIRST
Browse the site
02 · Mobile · 02 Growth

Growth: charge for it.

Live in the stores with paying users. Expo with EAS, a typed API you own, and device tests that run before a build is submitted.
Users
Hundreds to tens of thousands
Team
Two to five engineers, each with agents

You are here if

  • Users keep old versions for weeks after a release
  • A store rejection costs you a launch date
  • You need analytics, crash reporting and push that you own
  • The backend is your code, shared with a web product or not

Growth on mobile is about release discipline more than architecture. The app is still one Expo project, but the backend is now yours, the API is versioned, and a Maestro flow runs on a real device before every build. The agent keeps working in the JavaScript layer; native changes go through a config plugin and a full build, and are rare by design.

What changes when you leave this tier: a native capability with no good bridge, or enough engineers that per-platform teams become cheaper than a shared layer. Until then, stay cross-platform.

01

Consumer · content & social

Expo + EAS + your own typed API

The same Expo app, now behind a versioned API you own, with device tests and crash reporting before every build.

The stack

Framework
Expo + Expo Router, EAS Build and Update
Data
Your API (Hono or NestJS) over Postgres, with a CDN for media
Auth
Your provider, with refresh tokens handled in one place
Hosting
EAS for builds and updates, store releases on a cadence
Also
Sentry for crashes, PostHog for analyticsMaestro flows on real devices in CIPush through your API, not straight from a hosted backend
AGENTS.md + real projects on STACK IT FAST

Why agents do well here

4/5
  • A versioned API with generated types lets the agent change the backend without breaking the users still on last month's build.
  • Maestro flows are YAML the agent can read and extend, turning "does the feed still scroll" into a check it runs itself.
  • Everything is still TypeScript; native changes go through config plugins and remain rare.

Avoid at this tier

  • Breaking API changes; add fields, never remove them, until the old version's usage is zero.
  • A custom native module for performance you have not measured with the profiler.
  • Shipping a store build without the Maestro flows passing.

Growth moves the backend into your hands and the release process into CI. The app is still Expo, but every API call goes through a versioned, typed client, and every build runs device flows before it is submitted.

apps/mobile/      app/, src/features/, maestro/ (flows)
apps/api/         your backend with /v1 routes and OpenAPI
packages/api-client/  generated per API version

First five decisions: versioned API paths, generated client, Sentry and analytics before launch, Maestro on the three flows that matter, and a release cadence that is a calendar, not a reaction.

02

Companion · mobile face of a SaaS

Expo + shared packages + EAS

The monorepo grows up; the mobile app gets its own release pipeline while still sharing every type with the web app.

The stack

Framework
Expo + Expo Router in the product monorepo
Data
The product API, consumed through a shared generated client
Auth
The product's provider with native SDK and biometric unlock
Hosting
EAS Build and Update with a release channel per environment
Also
Shared design tokens through NativeWindMaestro flows for the mobile-only pathsDeep links mapped to the web app's URLs
AGENTS.md + real projects on STACK IT FAST

Why agents do well here

5/5
  • The shared client and schema packages mean the agent's backend change surfaces as a type error in the mobile app before anyone opens a phone.
  • Deep links that mirror web URLs let the agent reuse the web app's route knowledge for mobile navigation.
  • Release channels per environment make it safe for the agent to push updates to staging on every merge.

Avoid at this tier

  • Diverging the mobile data model from the web one; keep one schema package.
  • Rebuilding web features on mobile because they exist; keep the phone flows deliberate.
  • Native modules that only one platform needs, unless it is the product.

The companion app now has its own release pipeline but remains a consumer of the product’s API and schema. Deep links map to web URLs so the same notification or email works on either surface.

apps/web/
apps/mobile/      app/, src/features/, maestro/
apps/api/
packages/schema/  packages/api-client/  packages/tokens/

First five decisions: one schema package, deep links equal web URLs, release channels per environment, biometric unlock on top of the shared auth, and Maestro on the mobile-only flows.

03

Tool · offline-first utility

Expo + SQLite + optional sync

Local-first stays the default; sync, accounts and paid tiers are added as separate features with their own boundary.

The stack

Framework
Expo + Expo Router, EAS Build and Update
Data
expo-sqlite with Drizzle on device; PowerSync or a small Hono API for sync
Auth
Only for sync and purchases
Hosting
EAS; RevenueCat for in-app purchases
Also
NativeWindMaestro flows for the core workflowSentry
AGENTS.md + real projects on STACK IT FAST

Why agents do well here

4/5
  • Keeping local data as the source of truth means the agent can test the whole workflow without a network.
  • Sync as a separate feature with its own module keeps the hardest code in one place the agent can read in isolation.
  • Purchases through RevenueCat give the agent a documented SDK instead of two platforms' store APIs.

Avoid at this tier

  • Rewriting the app around a server database when sync is requested; add sync to the local one.
  • Handling store receipts yourself.
  • Sync engines you cannot debug from the client; prefer ones with visible queues.

The tool now pays for itself, so purchases and optional sync appear. Both are separate features behind a small boundary; the core workflow still works offline and is still what the device tests cover.

app/              index.tsx, item/[id].tsx, settings/, paywall.tsx
src/db/           schema.ts, migrations/, client.ts
src/features/     <workflow>/, sync/, purchases/
maestro/          core-workflow.yaml

First five decisions: local SQLite stays primary, sync as its own module, RevenueCat for purchases, accounts only when sync is on, and Maestro on the offline path first.