
Real-time social media app with 4 feed types (home, regional, trending, saved), Firebase RTDB chat with sub-collection pattern, chunked resumable media uploads, FCM push with deep linking, hashtag trending by velocity scoring, and location-based discovery. FlashList maintains 60 FPS scrolling through thousands of posts.
A look inside how the app is built: the decisions, trade-offs, and engineering that makes it work.
Screens never call APIs directly. Hooks orchestrate business logic. Services wrap external systems. Each layer is independently mockable and testable.
Screens → Hooks → Services: swap the whole backend (REST → GraphQL → Firebase) without touching a screen.
Feature-first folders (auth, feed, posts…) — self-contained with screens, hooks, services, types. Zero merge conflicts.
Zustand for client state, TanStack Query for server state. ~500 lines vs 3000+ Redux.
Home (algorithmic), regional (GPS), trending (velocity-scored hashtags), and saved (bookmarks). All use useInfiniteQuery + cursor pagination + FlashList.
4 feeds, one infinite query pattern: Home (algorithmic), Regional (GPS), Trending (velocity-scored), Saved (chronological).
Shopify FlashList with estimated item sizes + draw distance optimisation. 60 FPS across thousands of posts.
Optimistic updates for ALL interactions — like, follow, comment, share. Auto-rollback on failure. Feels 2-3x faster.
Chat metadata separate from messages. Inbox loads instantly. Message dedup via client UUIDs. Offline persistence. Presence tracking with activity timestamps.
Metadata separate from messages. Inbox loads ONLY metadata — lightweight and instant. Messages paginate 20 at a time.
Client UUID on every message. Retry with same UUID = Firebase rules prevent duplicates at DB level.
Real-time presence via onDisconnect handler. Typing indicators with 500ms debounce.
Auto-compression before upload. Video chunks resume from failure point. EXIF stripping for privacy.
12MB photo → 1920px resize → 70% compression (~300KB feed, ~100KB chat). 97% bandwidth reduction. Web Worker = zero frame drops.
Video chunks at 1MB with byte-range PUT. Fail at chunk 37/60? Resumes from 38. Never starts over.
EXIF stripped from all uploads unless user opts in. Firebase Storage rules enforce per-content-type access control.
Three layers keep things clean. Screens talk to hooks, hooks talk to services. Swap your whole backend without touching a screen.
Four feeds, one smooth pattern. Home, regional, trending, and saved. Each has its own cache so they never interfere.
Every interaction updates instantly. Follow, like, share the UI responds before the server does. If it fails, it rolls back silently.
Chat metadata loads instantly since messages load separately. 20 at a time. No duplicate messages even on slow networks.
Photos compress before upload. Videos split into 1MB chunks. Network drops at 60% Resume from 60%, not zero.
8 types of notifications with unique icons. Tap one and go to the exact screen. Read/unread state stays in sync.
Trending is based on how fast a hashtag is growing, not total count. A niche tag with a sudden spike beats a generic daily tag.
Zustand for client state, TanStack Query for server state. Clean separation, ~500 lines total instead of 3000+ Redux.