|
| 1 | +# HybridApp Philosophy |
| 2 | +This describes how the HybridApp architecture works and the conventions that MUST be followed when working with it. |
| 3 | + |
| 4 | +#### Terminology |
| 5 | +- **HybridApp** - The production app containing both "Expensify Classic" and "New Expensify" |
| 6 | +- **NewDot** - The new Expensify application (this repository) |
| 7 | +- **Mobile-Expensify** - Git submodule containing Expensify Classic code |
| 8 | +- **Standalone** - NewDot running independently without Classic integration |
| 9 | + |
| 10 | +## Overview |
| 11 | + |
| 12 | +Currently, the production Expensify app contains both "Expensify Classic" and "New Expensify". The file structure is as follows: |
| 13 | + |
| 14 | +- 📂 [**App**](https://github.com/Expensify/App) |
| 15 | + - 📂 [**android**](https://github.com/Expensify/App/tree/main/android): New Expensify Android specific code (not a part of HybridApp native code) |
| 16 | + - 📂 [**ios**](https://github.com/Expensify/App/tree/main/ios): New Expensify iOS specific code (not a part of HybridApp native code) |
| 17 | + - 📂 [**src**](https://github.com/Expensify/App/tree/main/src): New Expensify TypeScript logic |
| 18 | + - 📂 [**Mobile-Expensify**](https://github.com/Expensify/Mobile-Expensify): `git` submodule that is pointed to [Mobile-Expensify](https://github.com/Expensify/Mobile-Expensify) |
| 19 | + - 📂 [**Android**](https://github.com/Expensify/Mobile-Expensify/tree/main/Android): Expensify Classic Android specific code |
| 20 | + - 📂 [**iOS**](https://github.com/Expensify/Mobile-Expensify/tree/main/iOS): Expensify Classic iOS specific code |
| 21 | + - 📂 [**app**](https://github.com/Expensify/Mobile-Expensify/tree/main/app): Expensify Classic JavaScript logic (aka YAPL) |
| 22 | + |
| 23 | +You can only build HybridApp if you have been granted access to [`Mobile-Expensify`](https://github.com/Expensify/Mobile-Expensify). For most contributors, you will be working on the standalone NewDot application. |
| 24 | + |
| 25 | +## Rules |
| 26 | + |
| 27 | +### - Access to Mobile-Expensify repository is REQUIRED to build HybridApp |
| 28 | +For most contributors, you SHOULD work on the standalone NewDot application instead. |
| 29 | + |
| 30 | +### - Git submodule MUST be properly initialized and configured |
| 31 | +When working with HybridApp: |
| 32 | + |
| 33 | +1. Initialize the submodule: `git submodule init` |
| 34 | +2. Update the submodule: `git submodule update` |
| 35 | +3. Configure automatic updates: `git config --global submodule.recurse true` |
| 36 | + |
| 37 | +### - HybridApp native code MUST be accessed through Mobile-Expensify directories |
| 38 | +The native code for HybridApp is located in: |
| 39 | +- `./Mobile-Expensify/Android` (not `./android`) |
| 40 | +- `./Mobile-Expensify/iOS` (not `./ios`) |
| 41 | + |
| 42 | +Changes to `./android` and `./ios` folders at the root **will NOT affect HybridApp builds**. |
| 43 | + |
| 44 | +### - IDEs MUST open the correct workspace for HybridApp development |
| 45 | +To open HybridApp projects: |
| 46 | +- **Android Studio**: `./Mobile-Expensify/Android` |
| 47 | +- **Xcode**: `./Mobile-Expensify/iOS/Expensify.xcworkspace` |
| 48 | + |
| 49 | +### - Scripts automatically target HybridApp when Mobile-Expensify is present |
| 50 | +Default npm scripts target HybridApp when the submodule exists: |
| 51 | + |
| 52 | +| Command | Description | |
| 53 | +| --------------------- | ---------------------------------- | |
| 54 | +| `npm run android` | Build **HybridApp** for Android | |
| 55 | +| `npm run ios` | Build **HybridApp** for iOS | |
| 56 | +| `npm run ipad` | Build **HybridApp** for iPad | |
| 57 | +| `npm run ipad-sm` | Build **HybridApp** for small iPad | |
| 58 | +| `npm run pod-install` | Install pods for **HybridApp** | |
| 59 | +| `npm run clean` | Clean native code of **HybridApp** | |
| 60 | + |
| 61 | +### - Standalone scripts MUST be used when targeting NewDot only |
| 62 | +Append `-standalone` to target standalone NewDot: |
| 63 | + |
| 64 | +| Command | Description | |
| 65 | +| -------------------------------- | ----------------------------------------------------------- | |
| 66 | +| `npm run install-standalone` | Install standalone **NewDot** node modules (`npm install`) | |
| 67 | +| `npm run clean-standalone` | Clean native code for standalone **NewDot** | |
| 68 | +| `npm run android-standalone` | Build **NewDot** for Android in standalone mode | |
| 69 | +| `npm run ios-standalone` | Build **NewDot** for iOS in standalone mode | |
| 70 | +| `npm run pod-install-standalone` | Install pods for standalone **NewDot** | |
| 71 | +| `npm run ipad-standalone` | Build **NewDot** for iPad in standalone mode | |
| 72 | +| `npm run ipad-sm-standalone` | Build **NewDot** for small iPad in standalone mode | |
| 73 | + |
| 74 | +## Setup Instructions |
| 75 | + |
| 76 | +### Initial Setup |
| 77 | +1. Follow [NewDot setup instructions](https://github.com/Expensify/App?tab=readme-ov-file#getting-started) first |
| 78 | +2. Initialize submodule: `git submodule init` |
| 79 | +3. Update submodule: `git submodule update` |
| 80 | + - For faster setup: `git submodule update --init --progress --depth 100` |
| 81 | +4. Configure Git for automatic submodule updates: `git config --global submodule.recurse true` |
| 82 | + |
| 83 | +### Git Configuration |
| 84 | +If you have access to `Mobile-Expensify` and commands fail, add to `~/.gitconfig`: |
| 85 | + |
| 86 | +``` |
| 87 | +[url "https://github.com/"] |
| 88 | + insteadOf = ssh://git@github.com/ |
| 89 | +``` |
| 90 | + |
| 91 | +To prevent submodule changes from appearing in `git status`, add to `.git/config`: |
| 92 | + |
| 93 | +``` |
| 94 | +[submodule "Mobile-Expensify"] |
| 95 | + ignore = all |
| 96 | +``` |
| 97 | + |
| 98 | +### External Contributors and C+ Contributors |
| 99 | +If you need to modify `Mobile-Expensify` source code: |
| 100 | + |
| 101 | +1. Create your own fork of Mobile-Expensify |
| 102 | +2. Swap the origin: `cd Mobile-Expensify && git remote set-url origin <YOUR_FORK_URL>` |
| 103 | + |
| 104 | +## Submodule Management |
| 105 | + |
| 106 | +### - Submodule updates SHOULD be done carefully |
| 107 | +The `Mobile-Expensify` directory points to a specific commit. To update: |
| 108 | + |
| 109 | +- Download latest changes: `git submodule update --remote` |
| 110 | +- Manual update: Switch branches and pull within the `Mobile-Expensify` directory |
| 111 | + |
| 112 | +### - Submodule state MUST be considered when switching branches |
| 113 | +When switching branches, run `git submodule update` to ensure compatibility. |
| 114 | + |
| 115 | +## HybridApp-Specific Features |
| 116 | + |
| 117 | +### Patches |
| 118 | +- Patches are applied automatically during `npm install` |
| 119 | +- Add HybridApp-specific patches: `npx patch-package <PACKAGE_NAME> --patch-dir Mobile-Expensify/patches` |
| 120 | + |
| 121 | +### Additional Resources |
| 122 | +For extended documentation, troubleshooting, and pro tips, refer to [HYBRID_APP.md](contributingGuides/HYBRID_APP.md). |
0 commit comments