When most developers start building mobile applications, their folder structure usually looks something like this:
app/
components/
screens/
hooks/
utils/
For a small project, this works perfectly.
But imagine building:
- Instagram with millions of posts
- WhatsApp with billions of messages
- Uber with realtime location updates
- Netflix with massive content catalogs
Suddenly that simple folder structure starts falling apart.
Files become difficult to find.
Features become tightly coupled.
Navigation becomes messy.
Performance problems appear.
And onboarding new developers becomes painful.
The challenge is no longer writing screens.
The challenge becomes:
How do we organize a codebase that can survive years of development and dozens of engineers?
This is where architecture matters.
In this article we'll explore how modern large-scale applications could be structured today using Expo Router and modern React Native practices.
The goal is not to clone Instagram or Uber.
The goal is to understand the architectural thinking behind production-grade mobile applications.
Why Simple Folder Structures Fail at Scale
Most beginner applications are organized by file type.
Example:
components/
screens/
hooks/
services/
utils/
Initially this feels clean.
But after a few months:
components/
├── PostCard.tsx
├── UserAvatar.tsx
├── RideCard.tsx
├── PaymentCard.tsx
├── MessageBubble.tsx
├── VideoPlayer.tsx
Hundreds of files accumulate.
Finding related functionality becomes difficult.
The application becomes harder to maintain.
Small App Thinking vs Production Thinking
Small App Thinking:
Organize by file type
Production Thinking:
Organize by business feature
Large companies think in terms of:
- Feed
- Chat
- Profile
- Payments
- Notifications
- Authentication
Not buttons and screens.
Why Architecture Matters
Good architecture provides:
Scalability
Features can grow independently.
Maintainability
Developers know exactly where code belongs.
Team Collaboration
Multiple engineers can work simultaneously.
Performance
Systems remain efficient as complexity grows.
Developer Experience
Development stays predictable.
The Modern Expo Router Approach
Expo Router changed how React Native applications handle navigation.
Instead of manually defining navigation trees:
<Stack.Navigator>
Routes become file-system based.
Folders define application structure.
This encourages cleaner organization.
Production-Grade Expo Router Structure
A large application might look like:
app/
│
├── (public)/
│ ├── login.tsx
│ ├── register.tsx
│
├── (protected)/
│ ├── (tabs)/
│ │ ├── home.tsx
│ │ ├── profile.tsx
│ │ ├── settings.tsx
│
│ ├── chat/
│ ├── notifications/
│ ├── payments/
│
├── _layout.tsx
│
features/
│
├── auth/
├── feed/
├── chat/
├── profile/
├── notifications/
├── payments/
│
shared/
│
├── components/
├── hooks/
├── lib/
├── utils/
Notice something important.
Navigation and business logic are separated.
This becomes crucial at scale.
Feature-Based Architecture
Feature-based architecture is one of the most common patterns in large applications.
Instead of:
components/
screens/
services/
We organize by domain.
features/
├── auth/
├── feed/
├── chat/
├── profile/
├── payments/
Each feature owns its logic.
Example Feature Structure
features/chat/
├── components/
├── hooks/
├── services/
├── store/
├── types/
├── api/
Everything related to chat lives together.
This makes development significantly easier.
Authentication Flow Architecture
Every large application begins with authentication.
Examples:
- Instagram Login
- WhatsApp Registration
- Uber Authentication
- Netflix Profiles
A common route structure:
Expo Router route groups make this extremely clean.
Protected Routes
app/
(public)
(protected)
Users without authentication remain inside public routes.
Authenticated users gain access to protected routes.
This pattern scales extremely well.
Shared Layouts and Nested Routing
Large applications often share UI structures.
Example:
Instagram:
Bottom Tabs
Home
Search
Create
Reels
Profile
Every tab shares the same layout.
Expo Router handles this through nested layouts.
(tabs)
_layout.tsx
home.tsx
search.tsx
profile.tsx
This reduces duplication.
State Management at Scale
Small apps often rely only on React state.
useState()
Large applications require more structure.
State usually falls into three categories.
Server State
Data coming from APIs.
Examples:
- Feed posts
- Messages
- Movies
- User profiles
Typical solution:
TanStack Query
Client State
UI-related state.
Examples:
- Modal visibility
- Theme preferences
- Navigation state
Typical solutions:
Zustand
Redux Toolkit
Persistent State
Data stored between app launches.
Examples:
- Authentication tokens
- Cached preferences
- Offline data
Typical storage:
AsyncStorage
SecureStore
API Layer Architecture
A common mistake is calling APIs directly from screens.
Bad:
FeedScreen.tsx
↓
Fetch API
This creates tight coupling.
A better structure:
Example:
This separation improves testing and maintainability.
How Instagram Would Be Structured
Instagram appears simple.
But internally it contains multiple systems.
Feed System
Responsible for:
- Posts
- Likes
- Comments
- Media
Possible feature structure:
features/feed/
├── api/
├── components/
├── hooks/
├── store/
Media System
Handles:
- Image uploads
- Video uploads
- Compression
- Caching
A completely separate domain.
Notification System
Handles:
- Likes
- Comments
- Follows
- Mentions
Usually implemented as its own feature.
How WhatsApp Would Be Structured
WhatsApp is fundamentally a realtime system.
The complexity comes from messaging.
Not screens.
Chat Architecture
The realtime layer continuously synchronizes messages.
Realtime Messaging Flow
This flow repeats millions of times daily.
Offline Messaging
Messages must survive:
- No internet
- App crashes
- Device restarts
Architecture:
Offline-first thinking becomes essential.
How Uber Would Be Structured
Uber introduces a different challenge.
Realtime location.
Ride Tracking Architecture
Updates happen continuously.
State Management Challenges
Uber manages:
- User location
- Driver location
- Route data
- Ride status
All changing simultaneously.
Efficient state updates become critical.
Realtime Location Updates
Typical flow:
This architecture must remain efficient for thousands of concurrent rides.
How Netflix Would Be Structured
Netflix introduces another challenge.
Content delivery.
Content Discovery
Features:
Home Feed
Categories
Search
Recommendations
Each acts as an independent module.
Media Performance
Video streaming dominates architecture decisions.
Focus areas:
- Caching
- Prefetching
- Lazy loading
- Memory management
The challenge is not rendering UI.
The challenge is delivering content efficiently.
Offline Downloads
Netflix-style downloads require:
A dedicated subsystem is usually required.
Offline-First Architecture
Many successful mobile apps work even without internet.
Examples:
- Uber
- Spotify
- Netflix
Cache Synchronization Flow
The user experiences immediate feedback.
App Startup Optimization
Large applications often feel slow because too much work happens during startup.
Common Startup Problems
Authentication Check
API Calls
Fonts
Analytics
Remote Config
Feature Flags
All competing for resources.
Optimized Startup Flow
Prioritization matters.
Performance Considerations
Production applications optimize relentlessly.
Reduce Re-renders
Avoid unnecessary updates.
Code Splitting
Load features only when needed.
Image Optimization
Compress and cache media.
Virtualized Lists
Essential for feeds and chats.
Examples:
Instagram Feed
WhatsApp Chats
Netflix Catalogs
Shared Components
Create reusable building blocks.
Avatar
Button
Modal
Loader
Avoid duplicate implementations.
Scalability Challenges
Each application scales differently.
Challenge:
Media + Feed Ranking
Challenge:
Realtime Messaging
Uber
Challenge:
Realtime Location
Netflix
Challenge:
Massive Content Delivery
Tradeoffs Teams Make
Every architecture decision involves tradeoffs.
More Abstraction
Pros:
- Cleaner code
- Better reuse
Cons:
- Increased complexity
More Caching
Pros:
- Faster experience
Cons:
- Data consistency challenges
More Features
Pros:
- Better user experience
Cons:
- Larger maintenance burden
Final Thoughts
Most developers focus on building screens.
Large companies focus on building systems.
Instagram, WhatsApp, Uber, and Netflix succeed not because their UI is complex, but because their architecture allows thousands of engineers and millions of users to work together efficiently.
The progression usually looks like:
Small App
Screens
Components
Hooks
Medium App
Features
Services
State Management
Large App
Feature Architecture
Realtime Systems
Caching
Offline Support
Performance Optimization
Scalable Navigation
Expo Router fits naturally into this evolution.
Its file-based routing, nested layouts, route groups, and shared layouts make it an excellent foundation for large React Native applications.
The biggest lesson is simple:
Don't organize your application around screens.
Organize it around business features.
That's the mindset that separates tutorial projects from production-grade mobile applications.












Top comments (0)