Driver App engineering guide
Use this guide to develop and maintain the bare React Native Driver App. Store, API, operating-system, and third-party provider behavior also depends on the versions and configuration used by your deployment.
Architecture
The application separates shared headless logic, app-owned presentation, and native screen wiring:
index.js → App.tsx → src/DeliveryApp.tsx → src/appContainer.tsx
└→ src/navigators/RootNavigator.tsx
src/@/components shared headless controllers, hooks, and API client
src/ui Driver App presentation
src/pages thin screen wrappers
src/navigators authentication, schedule, permissions, push, and delivery navigation
src/context/hooks app-owned permission, theme, and location behavior
ios and android native projects and platform integrations
src/@/components is a Git submodule. The React Native @components alias resolves to its native entry point. Coordinate shared logic changes in the Components repository; do not edit the submodule as if it were ordinary app source.
Driver App startup can combine restored session state, configuration, network state, permissions, push registration, schedules, sockets, AppState handling, and foreground/background location. Preserve those ownership boundaries and avoid moving server authority into client presentation code.
Repository map
| Path | Responsibility |
|---|---|
App.tsx, src/DeliveryApp.tsx, src/appContainer.tsx | App entry and provider composition |
src/pages | Driver-facing screen wiring |
src/navigators | Authentication, schedule, tabs, delivery flow, push, sockets, and lifecycle wiring |
src/ui | App-owned UI components, layouts, providers, and presentation helpers |
src/context, src/hooks, src/providers | App-owned permission, location, theme, and storage behavior |
src/@/components | Pinned shared Components submodule |
src/config.json | Versioned runtime settings consumed by the app |
i18n | Translation catalog generation, validation, and synchronization tools |
ios, android | Native workspaces, projects, notification extension, manifests, and Gradle configuration |
jest, src/**/__tests__ | App tests and test suites |
Keep the @, @ui, and @components aliases aligned between babel.config.js and tsconfig.json.
Prerequisites and setup
- Install the React Native host requirements for the platform you will run: Xcode and CocoaPods for iOS, or Android Studio and a compatible JDK/Android SDK for Android.
- Use Yarn. The repository's
NODE_VERSION.txtselects Node 22, whilepackage.jsonaccepts Node 20 or newer. - Clone with submodules, or initialize them before installing dependencies.
git clone --recursive <authorized-repository-url>
cd <cloned-repository-directory>
yarn install --frozen-lockfile
For an existing clone:
git submodule update --init --recursive
yarn install --frozen-lockfile
For iOS, install the checked Ruby dependencies and Pods on the first setup and after native dependency changes:
bundle install
cd ios
bundle exec pod install
cd ..
Open ios/deliveryApp.xcworkspace when working in Xcode. The shared scheme is deliveryApp; the workspace also includes the notification-service extension. Use the checked Gradle wrapper for Android rather than a separately installed Gradle version.
Configure safely
src/config.json is a versioned application input, not a place for credentials. Keep secret keys, signing material, private hosts, customer records, tokens, orders, payment data, precise coordinates, notification payloads, and provider credentials out of source, logs, and bug reports.
Before launching the app, confirm that its packaged settings, Components revision, API and socket environments, push provider, location configuration, and native entitlements are configured for the same project. Do not copy values from another project or replace a configured endpoint with a guess.
Normal startup can initialize network, session, push, permission, socket, and location behavior before a delivery action is selected. Use a non-production environment and test accounts for development. Never use a production driver's account or route just to verify that the app starts.
Translation work should begin with local generation and verification. yarn i18n:sync is the documented dry run; yarn i18n:sync:live can write through an authorized API integration and must not be used as an exploratory command.
Run the app
Start Metro in one terminal:
yarn start
Run one platform from another terminal:
yarn ios
yarn android
If Metro has stale module state, use yarn start:reset. For native, notification-extension, permission, or background-location changes, rebuild the native target and validate on the affected platform; Fast Refresh is not sufficient.
Test and verify changes
Use the non-mutating lint command in local checks. The plain yarn lint script applies fixes.
npx tsc --noEmit
yarn lint:check
yarn test
yarn i18n:check-generated
yarn i18n:verify
Useful focused commands include:
yarn test path/to/file.test.tsx
yarn test:coverage
yarn test:coverage:summary
The app's CI workflow installs the frozen Yarn lockfile and runs lint, TypeScript, Jest, translation checks, and coverage. Jest covers app-owned test locations and excludes native folders and the Components submodule; validate a Components change in its own repository as well. Native verification must cover the relevant permission, denied/cancelled path, foreground/background transition, listener cleanup, and safe recovery—not only the successful screen state.
Use a non-production environment and test accounts for workflows that change orders, publish location, send messages, register notifications, or remove sessions and accounts. A client response alone does not confirm that the API or provider completed the action.
Build and release handoff
Create native development builds with the React Native CLI, Xcode workspace, notification extension, and Gradle wrapper. Store signing, distribution, rollout, and rollback are managed through your organization's release system.
Troubleshooting
| Symptom | Check |
|---|---|
@components cannot resolve | Confirm the submodule is initialized and that the alias targets the native entry point. |
| Metro resolves stale files | Stop Metro, run yarn start:reset, and rebuild after native changes. |
| iOS dependencies or extension symbols are missing | Run Bundler and bundle exec pod install from ios, then open the workspace rather than the project. |
| Android build configuration disagrees with the checkout | Use android/gradlew and verify the installed JDK/SDK against the checked React Native and Gradle files. |
| The app stops at authentication, permission, or schedule state | Identify the owning gate and inspect its dedicated contract before changing navigation. |
| Location or background callbacks persist unexpectedly | Stop the scenario, record non-sensitive lifecycle counts, and follow the background and location contracts. |
| Push and realtime disagree | Diagnose them as separate transports; neither proves the other is configured, authorized, or current. |
| An order action has an unknown result | Do not retry. Preserve the synthetic scenario and inspect server acceptance, grouped partiality, and follow-on effects through the mutation contract. |
| CI and local results differ | Compare Node, lockfile installation, submodule commit, generated translations, and the exact command variant. |
Security and escalation
Confirm that the app, Components revision, API environment, provider configuration, location purpose, and background entitlements are appropriate before running workflows that can affect real accounts or devices. When reporting a problem, include only the information needed to reproduce it and remove customer, account, location, and credential data.
Never paste credentials, raw configuration values, access tokens, customer/business/order details, precise coordinates, payment data, media, notification payloads, device identifiers, or signing material into an issue. Do not retry an ambiguous mutation, notification registration, message, review, external handoff, or location publication simply to see whether it worked.