The Context
I spent nearly two years as a core contributor on the Ohi App — a social networking platform that grew to 2M+ downloads and topped the App Store charts. Here's what I learned.
Performance is a Feature
At 2M users, performance regressions you didn't notice at 10K users become 1-star reviews. The things that moved the needle most:
FlatList optimization: Use getItemLayout when you know item heights. Use keyExtractor correctly. Avoid anonymous functions as renderItem props — they cause unnecessary re-renders.
Image loading: We switched to a custom image caching solution early on. Don't let images cause jank. Use priority on above-the-fold images.
JS thread: Keep the JS thread free. Heavy computation goes in background threads using InteractionManager or native modules.
CodePush is Your Best Friend
Shipping an app update through the App Store takes 1-3 days. With CodePush, a critical bug fix is live in minutes.
Our setup:
Detox for E2E Testing
Manual QA doesn't scale. We invested in Detox E2E tests for critical user flows (auth, core feed, notifications) and it paid off enormously. Caught regressions before they shipped.
Architecture Decisions That Paid Off
Redux Saga for side effects: Complex async flows (auth tokens, real-time subscriptions, optimistic updates) are much easier to reason about with sagas vs. thunks.
Reanimated for animations: Native-thread animations are non-negotiable for 60fps on lower-end Android devices. Never animate with the JS thread.
Feature flags: Let us gradually roll out features and quickly kill things that went wrong.
The biggest lesson: invest in observability (Sentry, analytics) from day one. You can't fix problems you can't see.