Fitnit · iOS · shot 24 Aug 2026

Onboarding,
every frame

Every screen of the flow, pulled off the simulator rather than drawn. Each has a slot beside it, so a redesign lands in the same board and the change is visible instead of described. All three carousel slides are filled in — photoreal plates generated on fal.ai with Fitnit's own UI composited on. Drag the scrubber to watch the flow change: it opened at fifteen frames and is down to thirteen.

13frames, down from 15
8questions, down from 9-that-was-10
45of 61 lost users were in the two screens now cut
19taps minimum, plus one name typed

iPhone 17 · iOS 26.2 · build 318 · light theme · captured by deep link + agent-device, unretouched · proposed slides rendered with landing.tsx's own type and control values

The whole flow at a glance

tap to jump

Reading order, top-left to bottom-right. Three are the pre-onboarding carousel, one is a modal sheet, one is the exit — the rest are the numbered questions. Two screens present at v1.117.1 no longer exist.

Revision

Height and weight split out · 24 Aug 2026 The BMI screen asked five things at once in three-line pickers. Height is now a full-page wheel — two columns for ft / in, one for cm — and weight is a full-page ruler you slide sideways with the figure set large above it. What remains of the calculator is age, sex and activity. Setup runs 1–10. The three welcome slides also shipped for real in v1.121.0 — the frames here are captures, not the v1.118.0 composites.

What the data says

PostHog · 10 Apr – 23 Aug 2026

279 people opened onboarding and 218 finished it — 78% completion. That headline is healthy, and it hides where the losses actually are.

Drop-off, step by step unique users

Opened onboarding279
1 · How did you hear about us?258−21
2 · What's your goal?234−24
3 · What should we call you?229−5
4 · Add a photonot measured
5 · Where are you from?226−3
6 · BMI Calculator221−5
7 · Your Results220−1
8 · What to focus on?220
9 · Main reason218−2
Finished218

Step 1 answers share of responses

Other9831%
Google Search8728%
Social Media6721%
Friends / Family4815%
News / Blog165%

Counts sum above the 258 who answered, because some people went back and changed their answer — read them as proportions.

Three quarters of all drop-off happens at or before the question that asks how you heard about us. Of the 61 people lost across the whole flow, 45 go in the first two screens — 21 between opening onboarding and answering step 1, and another 24 between step 1 and step 2. Every screen after that leaks single digits, and three of them leak nobody at all. The nine questions are not the problem. The first two are.

“Other” is the most popular answer, and it records nothing. At 31% it beats Google Search, Social Media and Friends / Family. There is no free-text follow-up, so those 98 people answered a question, cost themselves a screen, and told you nothing. That is the clearest single signal that the option list is wrong — if a third of people cannot find themselves in your five choices, the choices are not the ones people would offer unprompted.

Friends / Family is 15%, and that is the part attribution can never recover. AppsFlyer is deterministic for paid clicks and tracked links; a friend recommending the app at the gym is invisible to it. Worth noting that today it could not replace any of this: src/lib/appsflyer/index.ts:94-96 has both onInstallConversionDataListener and onDeepLinkListener switched off pending OneLink, so nothing in the app currently reads attribution at all.

The Social Media branch costs a screen and 30% of the people who take it. 67 chose Social Media at step 1; 47 completed “Which platform?”. This is also the one part of the question attribution genuinely does replace once OneLink is wired — which platform someone came from is exactly what a tracked link knows.

The photo step is not being measured. Since it shipped on 1 Aug, 50 people completed the step before it and 50 the step after — and it fired 1 event. The capture in photo.tsx:72 looks correct and sits on the only exit. The likely cause is next door: /photo is the only onboarding route missing from the PUBLIC_PATHS allow-list in app/_layout.tsx:155-172, and onboarding users are signed out, so reaching it should trip the redirect to /landing. Two independent signals agree; it still needs a signed-out reproduction to confirm.

Wrong before anything is redesigned

3 found

Each of these was in the shipped code and reproducible. Two are now fixed — kept here because the fix is the interesting part.

  1. Fixed v1.119.0The progress bar does not move on the branch

    app/(onboarding)/social-media.tsx:48 and welcome.tsx:55

    Resolved by deletion — both screens are gone. Both pass currentStep={1}. Answering “Social Media” — the first option on the very first question — advances a screen while the indicator stays exactly where it was. The one user who is told the flow is 9 steps long is also the one who sees 10 screens.

  2. bmi-results navigates during render

    app/(onboarding)/bmi-results.tsx:39–41

    When bmiData is null the component calls router.replace() in its body rather than in an effect. React logs “Cannot update a component while rendering a different component”; it is in .expo/dev/logs/start.log right now, and deep-linking fitnitios://bmi-results with no saved data reproduces it every time.

  3. /photo was missing from the auth allow-list

    app/_layout.tsx:155–172 — fixed in v1.119.0

    Every onboarding route is listed as public except one. Onboarding users are signed out, so reaching step 4 tripped the redirect to /landing and restarted their setup. It hid as an analytics gap: since the step shipped on 1 Aug, 50 people completed the step before it and 50 the step after, and it fired a single event. The capture in photo.tsx was correct the whole time — the bug was one line away, in a list.

  4. Reset Onboarding clears one of the two completion flags

    app/settings/data-privacy.tsx:94

    It sets hasCompletedOnboarding: false and leaves onboarding.completedAt set, though userStore.ts:560–561 writes them together. app/index.tsx:48 reads the first flag, app/_layout.tsx:179 reads the second, so after a reset the two gates disagree about whether this user has onboarded.

Screen by screen

now │ next

Left frame is what ships. The dashed frame beside it is where the replacement goes — re-run the capture after a change and this page updates in place, same URL.

Now
AI-powered rep counting
Next
proposed AI-powered rep counting

Pre · 1 of 3app/landing.tsx

AI-powered rep counting

Point your camera and Fitnit counts your reps and tracks your form in real time.

Control
Swipeable carousel, 3 slides, dot indicator
Primary
Get Started → /(onboarding)/welcome
Secondary
Already have an account? Sign in

The only screen with the brand green on the button. Every screen after it switches to black.

Now
Effortless nutrition tracking
Next
proposed Effortless nutrition tracking

Pre · 2 of 3app/landing.tsx

Effortless nutrition tracking

Snap a photo, scan a barcode, or search thousands of foods to log meals in seconds.

Control
Slide 2 of the same carousel
Primary
Get Started (persistent, does not change per slide)

Nothing forces a swipe. A user can tap Get Started on slide 1 and never see slides 2 and 3.

Now
Stay accountable with friends
Next
proposed Stay accountable with friends

Pre · 3 of 3app/landing.tsx

Stay accountable with friends

Daily challenges, leaderboards, and shared streaks keep you showing up.

Control
Slide 3 of the same carousel
Primary
Get Started
Now
How did you hear about us?
Next
not shot yet

Step 1 of 9app/(onboarding)/welcome.tsx

How did you hear about us?

We'd love to know how you found Fitnit

Options
Social Media · Google Search · News Article / Blog · Friends / Family · Other
Primary
Continue — disabled until one is picked
Back
Hidden (showBack={false})
Analytics
onboarding_started, onboarding_step_completed

GONE · Removed in v1.119.0. Attribution, asked before a single thing had been explained — the first question a brand-new user answered, and the screen with the worst drop-off in the flow.

Now
Which platform?
Next
not shot yet

Step 1 of 9 — againapp/(onboarding)/social-media.tsx

Which platform?

Tell us which social media brought you here

Shown when
The previous answer was Social Media — the first option in the list
Options
Facebook · Instagram · TikTok · YouTube · Twitter / X · Other
Primary
Continue → /(onboarding)/goal

This screen passes currentStep={1}, the same value welcome.tsx passes. The bar does not move when you advance.

Now
What's your goal?
Next
not shot yet

Step 2 of 9app/(onboarding)/goal.tsx

What's your goal?

This helps us personalize your experience

Options
Lose Weight · Gain Muscle · Maintain / Get Fit · Undecided
Detail
Each option carries a one-line subtitle — the first screen that does
Primary
Continue → /(onboarding)/name

Feeds the calorie target on step 7. Nothing on this screen says so.

Now
What should we call you?
Next
not shot yet

Step 3 of 9app/(onboarding)/name.tsx

What should we call you?

Enter your name or nickname

Control
Single centered text field, no keyboard visible until tapped
Primary
Continue → /(onboarding)/photo

The emptiest screen in the flow — one field on a full page. Also the only one that takes typing.

Now
Add a photo, {name}
Next
not shot yet

Step 4 of 9app/(onboarding)/photo.tsx

Add a photo, {name}

Friends will recognize you on the leaderboard. You can change it any time.

Controls
Take photo · Choose from library
Primary
Skip for now — the CTA is the skip
Personalised
Title interpolates the name from step 3

The only screen whose primary button is an escape hatch, and the only one that uses the previous answer in its title.

Now
Where are you from?
Next
not shot yet

Step 5 of 9app/(onboarding)/country.tsx

Where are you from?

This helps us set your measurement preferences

Control
Search field over a full alphabetical country list
Default
None — the list opens on Afghanistan with nothing selected
Primary
Continue → /(onboarding)/bmi-calculator

The device already knows the locale. A user in the US scrolls or types to find their own country.

Now
How tall are you?
Next
not shot yet

Step 5 of 10app/(onboarding)/height.tsx

How tall are you?

Scroll to your height

Control
Full-page vertical wheel — ft and in side by side, or a single cm column
Default
5 ft 10 in / 175 cm, or what was answered before
Feel
72pt rows, selection haptic per step, momentum snap
Primary
Continue → /(onboarding)/weight

One question, one control, the whole page. The selected row sits in a band at the exact vertical centre so a thumb rests where the answer is.

Now
How much do you weigh?
Next
not shot yet

Step 6 of 10app/(onboarding)/weight.tsx

How much do you weigh?

Slide the ruler to your current weight

Control
Full-width horizontal ruler — 1-unit ticks, labels every 10, green needle at centre
Readout
88pt figure above the ruler, updated on every tick
Range
80–500 lbs / 35–225 kg
Primary
Continue → /(onboarding)/bmi-calculator

Sideways on purpose: after a vertical wheel, the change of axis tells the hand this is a different quantity. Flinging 200pt moves about 24 lbs.

Now
BMI Calculator
Next
A little about you

Step 7 of 10app/(onboarding)/bmi-calculator.tsx

BMI Calculator → A little about you

Age, sex and how active you are set your daily calorie target

Was
Height · Weight · Age · Gender · Activity — five inputs, three of them 3-line pickers
Now
Age picker · Gender pair · Activity Level dropdown — height and weight moved to steps 5 and 6
Primary
Calculate BMI & Daily Calories — disabled until activity level is set
Size
459 → 402 lines

v1.120.0: the two measurements that deserved the whole page got it. Three inputs remain here, which is still the most of any step.

Now
Activity Level
Next
not shot yet

Step 7 · sheetapp/(onboarding)/bmi-calculator.tsx

Activity Level

Modal sheet over the calculator

Options
Sedentary · Lightly active · Moderately active · Very active · Extra active
Detail
Each carries its exercise-days description
Dismiss
Done, top right

The one control in onboarding that requires a second surface to answer.

Now
Your Results
Next
not shot yet

Step 7 of 9app/(onboarding)/bmi-results.tsx

Your Results

Your BMI and recommended daily calories

Shows
BMI figure, category word, four-band scale
Then
Select Your Goal — Maintain / Lose / Gain, each with its calorie number
Footnote
Mifflin-St Jeor equation, WHO categories, not medical advice
Primary
Continue → /(onboarding)/focus

With no BMI data this screen calls router.replace() inside the render body (line 41), which logs a React update-during-render warning.

Now
What would you like to focus on?
Next
not shot yet

Step 8 of 9app/(onboarding)/focus.tsx

What would you like to focus on?

Pick the area most important to you right now

Options
Nutrition · Physical Activity · Building Habits · Other
Primary
Continue → /(onboarding)/reason

Third goal-shaped question in the flow, after step 2 and the goal picker on step 7.

Now
What's your main reason for being here?
Next
not shot yet

Step 9 of 9app/(onboarding)/reason.tsx

What's your main reason for being here?

This helps us understand what motivates you

Options
Physical Appearance · Friends & Family · Become Healthier · Feel Better · Other
Primary
Get Started — the label changes here
Exits to
/subscription if signed in, otherwise /(auth)/signup?returnTo=/subscription

Fourth motivation question. The user has now answered goal, focus and reason without seeing anything the app does.

Now
You're Premium!
Next
not shot yet

Post · exitapp/subscription/

You're Premium!

What this account sees on exit

Captured as
A signed-in account that already holds the entitlement
New user sees
The real paywall — not reachable from this simulator state
Control
Close ×, top right

Honest caveat: this frame is not the new-user paywall. Re-shoot from a signed-out install to put the real one here.

Re-shooting this board

Every frame came from a booted simulator over a deep link, so the whole set is reproducible in about two minutes. Nothing here is a mockup.

Two frames need a caveat. Step 5 was captured with no country selected, because a deep link starts that screen clean. And the exit frame shows the already-premium state, not the paywall a new user meets — that one needs a signed-out install.

xcrun simctl openurl <udid> "fitnitios://welcome"
xcrun simctl io <udid> screenshot dl-welcome.png

# routes: landing welcome social-media goal name photo country
#         height weight bmi-calculator bmi-results focus reason