Bazaar Mobile is the customer-facing mobile application of the Bazaar marketplace platform, built with React Native and Expo. It enables users to browse and purchase products, manage their cart and wishlist, track orders, publish their own listings, and interact with the community through a review system. The app connects to the Bazaar microservices backend, supporting the full e-commerce lifecycle — from product discovery and secure checkout to delivery tracking and seller management.
- App Architecture
- Repository Map
- Technology Stack
- Getting Started
- Screens & Features
- Building & Deployment
- Code Quality & CI
- Contributing
Bazaar Mobile is structured around Expo Router v6 for file-based navigation, following a layered architecture that separates concerns across screens, components, services, and shared utilities.
┌─────────────────────────────────────────────────────────┐
│ Screens │
│ (app/ — Expo Router file-based routes) │
├─────────────────────────────────────────────────────────┤
│ Modules │
│ (layouts/, modules/, components/ — composed UI) │
├───────────────────────┬─────────────────────────────────┤
│ Contexts │ Hooks │
│ (cart, wishlist, │ (auth guard, search, │
│ user session) │ image picker, etc.) │
├───────────────────────┴─────────────────────────────────┤
│ Services │
│ (HTTP layer — auth, products, orders, cart, reviews) │
├─────────────────────────────────────────────────────────┤
│ Bazaar Backend │
│ (REST API gateway — microservices) │
└─────────────────────────────────────────────────────────┘
- File-based routing via Expo Router — screens live in
app/, grouped with(tabs)/and(home)/without affecting the URL - Protected routes via
ProtectedScreenlayout — wraps authenticated screens withuseAuthGuard - React Contexts for global state — cart, wishlist, and user session managed via
CartContext,WishlistContext, andUserContext - Service layer — all HTTP calls go through
baseService.ts, which injects auth headers and handles token refresh - React Compiler enabled — no manual
useMemo/useCallbackneeded - NativeWind v4 for styling — Tailwind CSS utility classes applied to React Native components via
className
bazaar-mobile/
├── app/ # File-based routes (Expo Router)
│ ├── _layout.tsx # Root layout: fonts, splash screen
│ ├── index.tsx # Initial redirect
│ ├── login.tsx # Login screen
│ ├── register.tsx # Registration
│ ├── forgot-password.tsx # Password recovery
│ ├── reset-password.tsx # Reset via link
│ └── (tabs)/ # Authenticated tab navigation
│ ├── _layout.tsx # Tab navigator + footer
│ ├── (home)/ # Home & search
│ ├── product/[id].tsx # Product detail
│ ├── profile/ # User profiles
│ ├── orders/ # Order history & detail
│ ├── sales/ # Seller sales management
│ ├── mypublications/ # User's listings
│ ├── checkout/ # Checkout flow
│ ├── new.tsx # Publish product
│ ├── cart.tsx # Shopping cart
│ └── favs.tsx # Wishlist
│
├── components/ # Reusable UI components
│ ├── ui/ # Atoms: Input, Button, Card, SearchBar…
│ ├── Cart/ # Cart item & summary components
│ ├── Checkout/ # Checkout flow components
│ ├── ProductCard/ # Product display card
│ ├── ProductForm/ # Product creation/editing form
│ ├── ImageUploader/ # Image picker & upload
│ └── ReviewsSection/ # Review display
│
├── modules/ # Feature-scoped component groups
│ ├── ProductSection/ # Product grid with pagination
│ ├── modals/ # FilterModal, SortModal, ImagePreviewModal
│ ├── ProfileModule/ # Public profile display
│ ├── ReviewsSection/ # Review listing
│ └── skeletons/ # Loading skeleton components
│
├── layouts/ # Screen layout wrappers (HOCs)
│ ├── ProtectedScreen/ # Authentication guard
│ ├── AuthLayout/ # Auth screens wrapper
│ ├── AuthFormLayout/ # Form styling wrapper
│ ├── CollapsibleHeaderLayout/# Animated scroll header
│ └── GlassModalLayout/ # Glass-morphism modal wrapper
│
├── contexts/ # React Context providers
│ ├── CartContext.tsx
│ ├── WishlistContext.tsx
│ └── UserContext.tsx
│
├── services/ # HTTP service layer
│ ├── baseService.ts # Generic fetch wrapper with auth & error handling
│ ├── authService.ts # Login, register, token refresh
│ ├── productsService.ts # Product CRUD
│ ├── ordersService.ts # Order operations
│ ├── cartService.ts # Cart management
│ ├── reviewsService.ts # Reviews
│ ├── userService.ts # User profile
│ └── wishlistService.ts # Wishlist
│
├── common/
│ ├── hooks/ # 12 custom hooks (auth, cart, search, etc.)
│ ├── helpers/ # Feature helpers (auth, products, orders…)
│ ├── interfaces/ # TypeScript type definitions
│ ├── constants/ # Categories, pagination limits, sort options
│ └── validators/ # Synchronous form validation functions
│
├── config/
│ └── api.ts # BASE_API_URL from environment variable
│
├── styles/
│ └── theme.ts # Color palette and fonts (Tailwind theme)
│
├── assets/images/ # Icons, logos, category images
├── app.json # Expo config (bundle ID, plugins, experiments)
├── eas.json # EAS build profiles
├── tailwind.config.js # NativeWind + Tailwind theme extension
└── tsconfig.json # TypeScript strict config with @/* alias
Navigation groups in parentheses —
(tabs),(home)— are Expo Router route groups and do not appear in the URL.
| Category | Technology | Version |
|---|---|---|
| Framework | React Native + Expo | 0.81.5 / 54.0.33 |
| Router | Expo Router | 6.0.23 |
| Language | TypeScript | 5.9.2 |
| Styling | NativeWind (Tailwind CSS) | 4.2.3 |
| Navigation | React Navigation | 7.x |
| Animation | React Native Reanimated + Skia | 4.1.1 / 2.2.12 |
| Gestures | React Native Gesture Handler | 2.28.0 |
| Images | Expo Image + Image Picker | 3.0.11 / 17.0.10 |
| Auth Storage | Expo Secure Store | 15.0.8 |
| OAuth | Expo Auth Session | 7.0.11 |
| Fonts | Expo Google Fonts (Inter, Righteous) | — |
| Notifications | React Native Toast Message | 2.3.3 |
| Build | EAS Build | ≥ 18.4.0 |
| Linting | ESLint + Prettier | 9.25.0 / 3.8.1 |
| Git Hooks | Husky | 9.1.7 |
- Node.js (v18+ recommended)
- Android Studio + Android SDK (for local Android builds)
ANDROID_HOMEenvironment variable:
export ANDROID_HOME=$HOME/Android/Sdk
export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-toolsAdd these lines to ~/.bashrc or ~/.zshrc to persist them.
git clone https://github.com/Baza-ar/bazaar-mobile
cd bazaar-mobile
npm installCopy .env.example to .env and fill in:
EXPO_PUBLIC_API_URL=<backend gateway URL>
EXPO_PUBLIC_ID_CLIENT_GOOGLE=<Google OAuth Android client ID>
EXPO_PUBLIC_ID_CLIENT_GOOGLEmust match theGOOGLE_CLIENT_IDconfigured inapi-auth.
npx expo start --clear| Key | Action |
|---|---|
a |
Open on Android emulator |
i |
Open on iOS simulator |
w |
Open in browser |
| QR | Scan with Expo Go app |
| Screen | Route |
|---|---|
| Login | /login |
| Register | /register |
| Forgot Password | /forgot-password |
| Reset Password | /reset-password |
| Feature | Route |
|---|---|
| Browse products (grid + filters) | /(tabs)/(home)/ |
| Search & sort | /(tabs)/(home)/search |
| Popular products | /(tabs)/(home)/popular-products |
| Product detail | /(tabs)/product/[id] |
| Product reviews | /(tabs)/product/reviews/[id] |
| Shopping cart | /(tabs)/cart |
| Wishlist | /(tabs)/favs |
| Checkout — delivery address | /(tabs)/checkout/delivery |
| Checkout — confirmation | /(tabs)/checkout/confirm |
| Order result (success / error / pending) | /(tabs)/checkout/{success,error,pending} |
| Order history | /(tabs)/orders |
| Order detail | /(tabs)/orders/[id] |
| Feature | Route |
|---|---|
| Publish product | /(tabs)/new |
| My publications | /(tabs)/mypublications |
| Sales management | /(tabs)/sales |
| Feature | Route |
|---|---|
| My profile | /(tabs)/profile |
| Edit profile | /(tabs)/profile/edit |
| Public seller profile | /(tabs)/profile/[id] |
| Seller's products | /(tabs)/profile/[id]/products |
| Seller's reviews | /(tabs)/profile/[id]/reviews |
1. Generate native project (only once, or after native dependency changes)
npx expo prebuild --platform android2. Bundle JS
npx expo export:embed \
--platform android \
--entry-file node_modules/expo-router/entry.js \
--bundle-output android/app/src/main/assets/index.android.bundle \
--assets-dest android/app/src/main/res \
--dev false3. Build APK
cd android && ./gradlew assembleDebugOutput: android/app/build/outputs/apk/debug/app-debug.apk
4. Install & launch
adb install -r android/app/build/outputs/apk/debug/app-debug.apk
adb shell monkey -p com.bazaar.mobile 1Run
adb devicesto verify the emulator is listed ifadbcan't find it.
Builds on Expo's servers — no local Android SDK required.
npm install -g eas-cli
eas login
eas build -p android --profile previewEAS provides a download link when the build completes. The latest preview build is available here.
| Profile | Purpose |
|---|---|
development |
Dev client with fast refresh |
preview |
Installable APK for internal testing |
production |
Signed APK/AAB for Play Store |
The free EAS plan allows 15 builds/month. For quick iteration, prefer local builds or Expo Go.
npm run lint # ESLint
npm run lint:fix # ESLint with auto-fix
npm run format # Prettier format
npm run format:check # Prettier check (CI mode)
npx tsc --noEmit # TypeScript type checkGit hooks via Husky run lint and format checks automatically before each commit.
Every push and pull request runs three parallel jobs:
| Job | Tool | Command |
|---|---|---|
| Lint | ESLint | npm run lint |
| Format | Prettier | npm run format:check |
| Type Check | TypeScript | npx tsc --noEmit |
See .github/workflows/ci.yml for the full configuration.
The UI was designed in Figma — refer to the wireframe before implementing new screens or components.
Before contributing, read AGENTS.md — it documents the conventions and patterns used across the codebase, including:
- Expo Router file-based routing rules
- NativeWind v4 styling conventions
- Service layer patterns (
baseService, error handling) - Auth guard implementation (
useAuthGuard,ProtectedScreen) - Form validation approach (synchronous, no external library)
- Navigation patterns and back-stack behavior
- Anti-patterns to avoid
| Branch | Purpose |
|---|---|
master |
Production-ready code |
feature/* |
New features |
fix/* |
Bug fixes |
All changes go through pull requests. The CI pipeline must pass before merging.