Stop tracking 60 events. Pick 6–10. Define your activation event before you write any tracking code. Watch the cohort retention curve, not total installs. One product analytics SDK + one crash tool. Defer attribution until you spend on ads.
Most React Native apps don't die from bad code. They die from invisible problems — users who never finished onboarding, a checkout step that lost half the funnel, a feature nobody opened after week one. You can't fix what you can't see.
The trap is that "set up analytics" gets pushed to next sprint, then the sprint after, then forever. By the time you actually look at your numbers, you've shipped three months of features blind. This post is the minimum viable analytics setup you should have running before you push to TestFlight.
The five questions every mobile app has to answer
AARRR — Acquisition, Activation, Retention, Referral, Revenue. Old framework, still right.
| Stage | Question | What you'd actually track |
|---|---|---|
| Acquisition | How do users find us? | Installs by channel, CPI |
| Activation | Did the first session land? | Onboarding complete, first key action |
| Retention | Do they come back? | D1/D7/D30, DAU/MAU |
| Referral | Do they bring friends? | Invite rate, viral coefficient |
| Revenue | Does any of this pay? | ARPU, LTV, conversion to paid |
You don't need a metric in every row on day one. You need to know which row is leaking the worst, and you can only know that if you can see all five.
The single most important event: activation
Pick a behavior that strongly correlates with week-two retention. Examples from real apps:
- Dropbox: "one file in one folder on two devices"
- Facebook (early): "seven friends in ten days"
- Fitness app: "logged one workout in first 48h"
Write this down before you write any tracking code:
A user is activated when they ___ within ___ minutes/days of installing.
This is the highest-leverage exercise in your first three months. Get this right and every other product decision becomes legible: does this change move more new users to activation?
Track this in your React Native app
A minimal event schema for any consumer mobile app. Pick a tool (Firebase, Amplitude, Mixpanel, or PostHog — they all have RN/Expo SDKs) and instrument these first:
// events.ts — your single source of truth
export const Events = {
APP_OPEN: 'app_open',
SIGN_UP_COMPLETE: 'sign_up_complete',
ONBOARDING_COMPLETE: 'onboarding_complete',
ACTIVATION: 'activation', // your one defined event
PURCHASE_COMPLETED: 'purchase_completed',
SHARE_INITIATED: 'share_initiated',
PUSH_RECEIVED: 'push_received',
PUSH_OPENED: 'push_opened',
} as const;
export type EventName = typeof Events[keyof typeof Events];
Tracking helper that's tool-agnostic, so you can swap providers without a rewrite:
// analytics.ts
import * as Posthog from 'posthog-react-native';
export const track = (event: EventName, props?: Record<string, unknown>) => {
if (__DEV__) console.log('[track]', event, props);
Posthog.capture(event, props);
};
// attach user properties at sign-up
export const identify = (userId: string, traits: Record<string, unknown>) => {
Posthog.identify(userId, traits);
};
Call sites stay clean and typed:
// in OnboardingScreen.tsx
import { track, Events } from '@/lib/analytics';
const handleComplete = async () => {
await saveProfile();
track(Events.ONBOARDING_COMPLETE, {
flow: 'signup_v2',
steps_skipped: skippedSteps.length,
});
navigation.replace('Home');
};
Three things this does that ad-hoc SDK calls don't:
-
Snake_case event names enforced via the const object — no
Purchase/purchase/purchasedItemdrift. -
Single switch point for swapping providers — change
analytics.ts, every call site keeps working. - DEV logging so you can verify events in the Metro console before they hit production.
User properties (do this once, slice everything forever)
The biggest analytics regret most teams have is not setting user properties on day one. Once they're attached, every event you've ever tracked becomes sliceable by them retroactively.
// on first install
identify(userId, {
install_source: 'organic', // or attribution source
signup_date: new Date().toISOString(),
platform: Platform.OS, // 'ios' | 'android'
app_version: DeviceInfo.getVersion(),
});
// on plan change
identify(userId, { plan: 'pro' });
Now you can ask "what's D7 retention for organic-install Pro users on iOS?" without touching tracking code again.
The chart that matters more than DAU
The single most useful chart in mobile analytics is the cohort retention curve — a triangle where each row is the install week and each column is the percentage of that cohort still active N weeks later.
If the curve flattens around D30, you have something. If it keeps dropping toward zero, you don't — no matter what the install counter says. Most analytics tools (Amplitude, Mixpanel, PostHog) ship this view out of the box; Firebase requires a bit more setup.
Vanity metrics to delete from your dashboard
These always go up, which is exactly why they're useless for decisions:
- Total installs
- Total registered users
- Total screen views without context
- Followers on social
- Average time in app, isolated
Replace each with a ratio or a cohort:
- Total installs (12,438)
+ 30-day retained users from last month's installs (1,247 / 9,800 = 12.7%)
- Page views (84,221)
+ Screen views per session for activated users (median 14)
- Average session length (4m 12s)
+ % of sessions where activation event fired (38%)
The discipline of converting absolute numbers to ratios is the difference between a dashboard and a decision-making tool.
Day-one stack (don't overthink this)
✅ ONE product analytics SDK → Firebase | Amplitude | Mixpanel | PostHog
✅ ONE crash tracker → Sentry (or Crashlytics)
✅ 6–10 events → not 60
✅ Snake_case names → enforced in a const object
✅ User properties attached → on sign-up + on plan change
⏸️ Attribution (AppsFlyer/Adjust) → defer until you spend on paid acquisition
⏸️ Session replay → defer until activation rate stabilizes
⏸️ A/B testing platform → defer until you have a hypothesis worth testing
Stack three analytics tools on launch day and you'll end up with three half-broken instrumentations and zero confidence in the data.
The build–measure–learn loop, for real
The teams that compound are the ones who decided, on day one, which question they were trying to answer — and built the tracking against that question first. They didn't install Mixpanel and then figure out what to track. They figured out the activation event first, then picked the tool, then built the screens.
If you're earlier than that — still figuring out what the app even is — the bigger lever is speed of iteration, not analytics tooling. The faster you can put a build in front of real users and watch what they do, the sooner you'll know what to instrument in the first place. RapidNative generates real React Native + Expo source from a prompt — meaning you ship, instrument with the snippets above, watch what happens, and iterate in hours instead of sprints. The code is yours, so swapping in PostHog or Amplitude is just a normal RN package install.
Quick FAQ
How many events should a new app track?
6–10. Tracking 60 on day one almost guarantees none of them will be reliable.
What's a good D1 retention rate?
Rough rule: 25–40% for consumer apps. The shape of the curve matters more than any single day — does it flatten, or keep falling?
Do I need a paid tool for an MVP?
No. Firebase is free, has solid RN/Expo SDKs, and covers events, funnels, and retention. Most MVPs don't outgrow it until they have meaningful revenue.
Mixpanel vs Amplitude vs PostHog for React Native?
All three have first-class RN SDKs. Amplitude has the strongest cohort UI for product-led growth teams. Mixpanel has mature reports and a generous free tier. PostHog is open-source-friendly and self-hostable if you care about data ownership. Firebase is the free default if integrated with the rest of Google's stack matters more than UI polish.
What are you tracking in your React Native app right now — and which event do you wish you'd instrumented from day one? Drop a comment with your activation event; I'm collecting examples from the indie dev side.
Top comments (0)