> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vibely.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# From idea to the App Store

> One mobile app carried end to end — Streakly, a habit tracker, from a one-line idea to a listing under review

This guide carries a single app the whole way: **Streakly**, a habit tracker. One line of idea, a plan, a design direction, a few build loops, a real backend, native permissions, an icon, screenshots, and a submission.

It is deliberately a *mobile* arc, because that is the part that does not end at a URL. The last third — icon, screenshots, listing, review, first update — has no web equivalent, and it is where most first-time shippers stall. For the web version of this arc, see the blog post [Idea to live URL in 60 seconds](https://vibely.sh/blog/idea-to-live-url-in-60-seconds).

Each stage links to the reference page that documents it rather than re-explaining it.

***

<Frame>
  <img src="https://cdn.vibely.sh/doc/v1/guides-from-idea-to-store.webp" alt="Streakly, idea to App Store" width="1200" height="675" />
</Frame>

## 1. Shape the idea

The first prompt decides the shape of everything after it, so spend two minutes narrowing before you type.

Three questions:

| Question | Streakly's answer |
| - | - |
| Who opens this, and when? | One person, first thing in the morning and last thing at night. |
| What is the single action? | Tick a habit off for today. |
| What do they get for it? | A streak they don't want to break. |

That is the whole V1. Everything else — social sharing, a friends leaderboard, widgets — is a later turn. An app that does one thing completely beats an app that stubs six.

Turn it into a prompt by naming the job, the sections, the platform constraints and the feel:

```text theme={"system"}
Build Streakly, a habit tracker, as a mobile app.

The one job: see today's habits, tick one off, and open a habit to see its streak.
Bottom tabs for Today / Stats / Settings, plus a modal sheet for adding a habit.
Portrait only. What I create has to survive an app restart.
Vibe: calm and warm — big tap targets, soft shadows, generous spacing.
```

Compare that with "build a habit tracker". Both build something. Only one builds Streakly.

<Tip>
  If you can't answer "what is the single action", you are not ready to prompt — you are ready to think. Ask the agent instead: "I want to build something for people who keep forgetting their habits. Ask me five questions before we design anything."
</Tip>

## 2. Plan before you build

Turn 1 does not need a plan — the brief above is the plan. The turn that *does* need one is the first change that touches many files at once.

For Streakly that was making streaks survive a change of timezone, which turned out to touch storage, the day boundary, the streak calculation and the reminder time. One read-only turn first:

```text theme={"system"}
Switch to plan mode. Don't change anything.

I want streaks to be correct when someone travels across timezones. Read how we
store completions and how the streak is computed, and tell me everything that
would have to change — including anything already stored that would become wrong.
```

What came back named a problem the prompt did not: completions were stored as local dates, so an existing user flying east would lose a day. That is a data migration, and finding it before the build is the entire value of the turn.

Plan mode is read-only — the agent can read, search and reason but cannot write a file. Read the plan, argue with it, then say "go ahead and implement that". Details in [Iterate → Plan mode](/features/web-apps/iterate#2-plan-mode).

## 3. Set the design direction early

Direction is cheap on turn 1 and expensive on turn 40, because it lives in the theme constants and every screen written after it inherits it.

Say it in the words that move things:

```text theme={"system"}
Direction: calm and warm. A soft sand background rather than pure white, one
muted green accent, rounded corners, generous line height, almost no shadow.
No purple. Apply it to both colour schemes, not just light.
```

Three things worth naming explicitly on mobile:

* **A hue the domain actually wears.** Purple or violet as a default accent is the single loudest tell of a generated app. Habit tracking wears green, warm neutrals, terracotta — pick one.
* **Both colour schemes.** Dark mode is OS-driven. A screen that looks right in the light preview can be unreadable on a phone at night if any colour was written as a hex literal instead of a theme token.
* **Type.** Loading a real font family is the loudest single change you can make — every screen is mostly text, and an app on the system face reads like every other app on the phone whatever the palette does.

You are not starting from nothing. The floor — 16pt minimum reading copy, 44×44pt touch targets, labelled controls, contrast in both schemes — holds on every build regardless of direction.

## 4. Build in small loops

After turn 1, one thing per turn. Streakly's first ten turns, roughly:

| Turn | Prompt |
| - | - |
| 1 | The brief from stage 1 |
| 2 | "The Today screen should show how many are left, not the app name, as its heading." |
| 3 | "Add a streak badge to each row — current streak, and a flame once it's past 7." |
| 4 | "Tapping a row opens a detail screen with a 30-day heatmap." |
| 5 | "Add a reorder mode so I can drag habits into the order I do them." |
| 6 | "Archive instead of delete — archived habits keep their history and don't show on Today." |
| 7 | "Empty state on Today when everything's done: say so and show the streak, don't show an empty list." |
| … | … |

Each of those lands cleanly because each names one thing. A turn that asked for all six would have produced six shallow attempts.

Full loop, including the QR handoff: [Build your first mobile app](/features/mobile-apps/quickstart).

## 5. Web preview versus Expo Go on a real device

You get two surfaces, and using the wrong one costs hours.

The **web preview** in the right pane is instant and is where layout, navigation, forms and logic belong. **Expo Go** on your phone is the truth, and is the only place camera, push, biometrics, secure storage and the real feel of a tap exist.

The trap is believing a native feature is broken because it did nothing in the browser. It was never going to. The full matrix of what works where is in [Web preview vs Expo Go](/features/mobile-apps/quickstart#web-preview-vs-expo-go-when-to-use-which).

Rule of thumb for Streakly, and for anything else: iterate in the preview, and never say "ship it" without one pass on the device.

## 6. Add the backend when data needs to survive

Streakly ran for a dozen turns with no backend at all, on device storage. That was correct. A habit log that only you can see does not need a database.

The backend arrives with a *requirement*, not a hunch. For Streakly it was "I want the same habits on my iPad." That is sync, which is accounts, which is Supabase.

```text theme={"system"}
Add accounts so my habits sync across devices. Email and password sign-in and
sign-up screens, an auth gate on the tabs, and migrate what's already stored on
the device into my account the first time I sign in.
```

Two things worth knowing before you ask:

* Connecting is non-blocking. The agent raises the connect card and keeps building the screens in the same turn; they rewire themselves once the connection lands.
* Every table ships with row-level security in the same migration. The app's key is in the bundle and can be read out of it, so the policies are the only thing standing between your users' data and everyone else's.

See [Connectors → Overview](/integrations/connectors/overview) and [Connectors → Auth](/integrations/connectors/auth).

## 7. Native capabilities

Streakly needed exactly two: a daily reminder, and Face ID on the journal notes.

```text theme={"system"}
Add reminders. A time picker in Settings, permission asked the moment they flip
the toggle on, and a daily local notification at that time. Tapping it should
open the Today tab.
```

Two rules the agent follows and you should know about:

* **Permission at the moment of use**, never on launch. Reviewers reject apps that ask for everything up front, and users decline them.
* **The permission config ships in the same turn as the module.** Apple auto-rejects a build whose `Info.plist` is missing a usage description; on Android a missing permission fails *silently* at runtime — Android 13+ will show no notification at all without `POST_NOTIFICATIONS`, and nothing errors.

Camera, push, biometrics, geolocation, secure storage and deep links: [Native capabilities](/features/mobile-apps/native).

## 8. App icon and store screenshots

This is the stage with no reference page, because it is the stage that is half yours.

### What the build produces

You author **one** file — `assets/images/icon.png`, a square mark, full-bleed, no baked-in rounded corners and no margin of its own, because every platform applies its own mask. On a mobile first build the agent generates it, overwrites the placeholder, reuses the art for `splash-icon.png` and `favicon.png`, and sets the splash and adaptive-icon background colours in `app.json` to carry your direction.

Everything below is derived from that one file on every build. Do not hand-author any of it:

| Derived artefact | What it is |
| - | - |
| Android adaptive foreground | Fitted to the 66dp keyline inside the 108dp canvas |
| Android themed layer | Alpha-only silhouette, tinted by the wallpaper |
| iOS light / dark / tinted appearances | Written into `app.json` for you; light and tinted ship with no alpha channel |
| Per-density mipmaps and the iOS icon set | Generated during prebuild |
| Play listing icon | Exactly 512×512, opaque, at `assets/images/play-store-icon.png` |

<Warning>
  A production build is **refused** while `icon.png` is still the shipped placeholder, and the check compares bytes — "close enough" does not pass. If a build is rejected for this, the icon was generated somewhere other than `assets/images/icon.png`.
</Warning>

Two things that quietly ruin a branded build: leaving both `backgroundColor` values in `app.json` at `#FFFFFF` (a finished mark then sits in a white ring on Android and flashes a white launch screen), and leaving `expo.name` at the template default, which is what appears under the icon on the home screen.

If your app sends notifications, the Android notification icon is a **separate** asset and is not derived from the app icon. It must be a white-on-transparent silhouette; anything with colour renders as a solid white square on Android 5 and up.

### What the stores demand

The app icon is a build artefact. **Everything else on the listing is metadata that never ships inside the binary**, and nothing in the project derives it.

| Asset | iOS | Android |
| - | - | - |
| Store icon | 1024×1024, sRGB or Display P3, square, no pre-rounded corners, **no alpha channel** on the light appearance | 512×512, 32-bit PNG, under 1 MB — derived for you, still uploaded by you |
| Phone screenshots | Required, uploaded per device size in App Store Connect | 2–8 required |
| Feature graphic | — | 1024×500, required before the listing can go public |
| App preview video | Optional | Optional |

Screenshot dimensions change when the stores add a device size, so take the required sizes from App Store Connect and Play Console at the moment you upload rather than from any doc, including this one.

### What you still have to make

* **The screenshots themselves.** Nothing generates them. Take them on the largest device size each store currently requires, from a build with real seeded data — not an empty state, and not lorem ipsum.
* **The framing.** Plain device captures are allowed on both stores. A short headline over each one converts better, and the agent can write those headlines from what the app does.
* **The listing copy.** Name, subtitle, description, keywords. Ask for it — it is the one part of stage 8 the agent does well, and it is drafted from the actual app rather than from your memory of it.
* **The upload.** Neither store's API accepts a listing from a build. Screenshots, feature graphic, store icon and copy go in by hand, once.

<Note>
  Pushing the derived 512×512 icon to a live Play listing is a separate, explicitly requested step — never a side effect of submitting a build, because the listing is public and shared across every track.
</Note>

## 9. Store listing, review, and the first update

Connect Expo, run a `production` build, and EAS uploads it to App Store Connect or Play. On iOS you fill out the listing, submit for review (currently averaging 24–48 hours, longer for a first submission) and release. On Play you pick a track, submit, and promote forward when you are ready — internal, then closed, then open, then production, and Play's first review can take up to a week.

TestFlight, Play tracks and promotion, the rejection list, OTA versus native updates, and rollbacks are all documented in [Ship to stores](/features/mobile-apps/ship) — that page is the reference for this stage, and this guide will not repeat it.

Two things worth internalising before your first submission. **A rejection costs almost nothing**: builds, updates and store submissions are not metered, so only the one turn that triggered the build is charged, and resubmitting is free. And **the first update is the real test** — paste the reviewer's note verbatim into the chat, guideline number included, and ask the agent to work out what in the app triggered it.

***

## Next

<CardGroup cols={2}>
  <Card title="Prompt library" icon="clipboard-list" href="/prompting/library">
    Every prompt in this guide, plus the six mobile-only ones.
  </Card>

  <Card title="Ship to stores" icon="apple" href="/features/mobile-apps/ship">
    EAS builds, TestFlight, Play tracks, rollbacks.
  </Card>

  <Card title="Native capabilities" icon="mobile-screen" href="/features/mobile-apps/native">
    Camera, push, biometrics, deep links.
  </Card>

  <Card title="Debugging" icon="bug" href="/prompting/debugging">
    When the build and the store both say no.
  </Card>
</CardGroup>


## Related topics

- [App Store optimization](/features/mobile-apps/aso.md)
- [Ship to stores](/features/mobile-apps/ship.md)
- [Publish your Vibely project](/features/deploy/publish.md)
- [Add a third-party analytics tool](/integrations/connectors/analytics.md)
- [Quick start](/introduction/quickstart.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.