Architecture
Expo Router File-Based Routing
The app uses Expo Router (v6) for file-based routing. All route files live under src/app/.
Top-Level Routes
src/app/
_layout.tsx # Root layout (providers, splash screen, Sentry)
index.tsx # Entry redirect
sign-in.tsx # Sign-in modal
modal.tsx # Generic modal route
+not-found.tsx # 404 fallback
(tabs)/ # Main tab navigator
(auth)/ # Auth flow stack
house/ # House detail routes (outside tabs)
perk-info/ # Perk detail routes (outside tabs)
explore-search/ # Search screen
likes-request-info.tsxTab Navigation Structure
Defined in src/app/(tabs)/_layout.tsx using a CustomTabBar component (src/components/custom-tab-bar.tsx).
| Tab | Route Group | Description |
|---|---|---|
| explore | (tabs)/explore/ | House listings, map, roomie, rideshare |
| viewings | (tabs)/viewings/ | Viewing requests, inquiries, rental |
| bills | (tabs)/bills/ | Bills landing, quotes, signup, meters (UK only, hidden in US mode) |
| promotions | (tabs)/promotions/ | Perks, events, and wallet sub-tabs |
| profile | (tabs)/profile/ | Account, house, housemates |
| likes | (tabs)/likes/ | Liked houses and groups (href: null — not shown in tab bar) |
The bills tab is conditionally hidden when isUsaMode is true. The viewings tab title changes to “rental” when the HOUSR_2_0 feature flag is enabled.
Nested Route Groups
Explore sub-routes:
explore/roomie/— Roommate matching (profile setup, explore, chat)explore/rideshare/— Rideshare (create ride, search, chat, driver dashboard)
Promotions sub-tabs:
promotions/(tabs)/perks.tsx— Perks listingpromotions/(tabs)/events.tsx— Events listingpromotions/(tabs)/wallet.tsx— Wallet (tokens + tickets)promotions/(perks)/— Perk search, redeem, info
House detail routes (outside tabs):
house/[id].tsx— House overviewhouse/filters.tsx— Filter screenhouse/overview/— Video tour, building listings, EPC, floorplan, map
Provider Hierarchy
The full provider tree from src/app/_layout.tsx:
ErrorBoundary
GestureHandlerRootView
BottomSheetModalProvider
AuthProvider # JWT + user state, sits outside QueryProvider
RootLayoutNav
QueryProvider # React Query client
MixpanelInitializer # Analytics init
FeatureFlagProvider # Remote feature flags from API
NotificationProvider # FCM + Notifee push notifications
ToastProvider # App-wide toast notifications
DeviceCityProvider # Device-level city selection (persisted)
CitiesProvider # Cities list from API
ExploreFiltersProvider # Search filters + sort (persisted)
NavigationGuardProvider # Auth-gated route protection
ThemeProvider # React Navigation theme
Stack # Root stack navigatorKey detail: AuthProvider wraps everything including QueryProvider, so auth state is available before any queries fire. The AnimatedSplash screen shows until fonts load and auth state resolves.
Feature-Based Module Structure
Code lives in src/ with path alias @/ mapped to src/.
src/
app/ # Expo Router routes (screens)
features/ # Domain modules
auth/ # Auth components, API, types
explore/ # House discovery (api, components, hooks, context, types, utils, widgets)
viewings/ # Viewing management
bills/ # Bills (UK only)
events/ # Events
perks/ # Perks
wallet/ # Tokens + tickets
roomie/ # Roommate matching
rideshare/ # Ridesharing
screens/ # Server-driven UI engine
explore-search/ # Search feature
dev/ # Developer tools
components/ # Shared UI components
context/ # Global context providers
providers/ # Query provider
lib/ # Core services (axios, firebase, auth, token storage, deep links, mixpanel)
hooks/ # Shared hooks
config/ # Environment config (env.ts)
constants/ # Theme, design system
utils/ # Shared utilitiesEach feature module follows a consistent internal structure:
features/<name>/
api/ # Raw API call functions
hooks/ # React Query hooks or custom hooks wrapping API calls
components/ # Feature-specific UI components
context/ # Feature-specific context providers
types/ # TypeScript interfaces and types
utils/ # Feature-specific utilities
constants/ # Feature-specific constants
assets/ # Feature-specific images, animations
screens/ # Full screen components (some features)
widgets/ # Reusable widget componentsServer-Driven UI
The src/features/screens/ module implements a server-driven UI engine. The API returns screen configurations (widgets, layout), and the engine (engine.tsx) renders them using a widget registry (registry.ts) and strategy pattern (strategies/). Used for the perks screen layout.