Local Development Setup¶
This app uses Expo SDK 54, Expo Router, and a custom development client (expo-dev-client). It is not compatible with Expo Go.
Prerequisites¶
- Node.js
^18.17.0or>=20.5.0 - npm
10.9.7(pinned inpackage.json; use npm, not pnpm) - Xcode and CocoaPods for iOS development
- Android Studio for Android development (Android native project is generated on first build)
First-time setup checklist¶
Run these steps in order:
- Clone the repository
npm installcp .env.example .envand fill in real backend and Firebase values- Ensure the
ios/directory exists (see How you get theios/directory) cd ios && pod install && cd ..- Terminal 1:
npx expo start -c - Terminal 2:
npm run ios(ornpm run android)
Do not skip step 6. Metro must be running before the native app launches.
How you get the ios/ directory¶
The ios/ folder is the native Xcode project. It is required for iOS development on this app. It is not created by npm install and it is not stored in git.
This repository uses Expo prebuild. Every developer generates ios/ locally from app.config.ts.
Generate ios/ after cloning¶
From the repository root, with .env already configured:
npx expo prebuild --platform ios
This reads app.config.ts and creates:
ios/Podfileios/Gezen.xcodeprojios/Gezen/native app sources
Then install pods:
cd ios
pod install
cd ..
npm run ios can also trigger native project generation when ios/ is missing, but running npx expo prebuild --platform ios first makes the setup explicit and easier to debug.
Do not commit ios/ to git. It is listed in .gitignore because it is machine-generated and can be recreated at any time.
Generate android/ when it is missing¶
This repository may not ship an android/ folder. For Android, generate it the same way:
npx expo prebuild --platform android
npm run android
When to regenerate ios/¶
Regenerate native projects only when:
- You added or removed a native Expo module
- Expo told you to add a plugin in
app.config.ts ios/is corrupted or out of sync with dependencies
Command:
npx expo prebuild --clean --platform ios
cd ios && pod install && cd ..
npm run ios
--clean deletes and recreates ios/. Do not run it casually if you have manual native edits you need to keep.
What you should not do¶
- Do not expect
npm installto createios/ - Do not use Expo Go for this project
- Do not edit native code in
ios/unless you know you need a custom native change
Install dependencies¶
npm install
Configure environment variables¶
Copy the example file and fill in real values:
cp .env.example .env
Backend API URLs¶
The frontend does not hardcode backend IP or port. It reads full URLs from .env.
| Variable | Purpose | Required format |
|---|---|---|
EXPO_PUBLIC_API_URL |
Main backend | Full URL including /api, for example http://192.168.10.135:8000/api |
EXPO_PUBLIC_TASK_PHOTO_API_URL |
Task photo backend | Full URL including /api/v1, for example http://192.168.10.135:8000/api/v1 |
Example .env for a backend on your local network:
EXPO_PUBLIC_API_URL=http://192.168.10.135:8000/api
EXPO_PUBLIC_TASK_PHOTO_API_URL=http://192.168.10.135:8000/api/v1
Example .env for production-style HTTPS:
EXPO_PUBLIC_API_URL=https://sales.iqvizyon.com/api
EXPO_PUBLIC_TASK_PHOTO_API_URL=https://api.example.com/api/v1
The app sends requests like POST /auth/token to:
<EXPO_PUBLIC_API_URL>/auth/token
Firebase and other required variables¶
| Variable | Purpose |
|---|---|
EXPO_PUBLIC_FIREBASE_PROJECT_ID |
Firebase project ID |
EXPO_PUBLIC_FIREBASE_STORAGE_BUCKET |
Firebase storage bucket |
EXPO_PUBLIC_FIREBASE_MESSAGING_SENDER_ID |
Firebase messaging sender ID |
EXPO_PUBLIC_FIREBASE_IOS_API_KEY |
Firebase iOS API key |
EXPO_PUBLIC_FIREBASE_IOS_APP_ID |
Firebase iOS app ID |
EXPO_PUBLIC_FIREBASE_ANDROID_API_KEY |
Firebase Android API key |
EXPO_PUBLIC_FIREBASE_ANDROID_APP_ID |
Firebase Android app ID |
The app refuses to boot if any required value is missing. Values are loaded through app.config.ts into Expo runtime config and read by app/config/runtimeConfig.ts.
Legacy file to ignore¶
app/constants.ts contains old commented API URLs. The app does not use that file for network calls. Only .env matters.
After changing .env¶
Expo reads .env when Metro starts. Saving .env is not enough while Metro is already running.
- Stop Metro (
Ctrl+C) - Restart with cache cleared:
npx expo start -c
- Relaunch the app from the simulator or run
npm run iosagain
You do not need a native rebuild for ordinary .env changes. You do need a Metro restart.
To verify the app picked up the new URL, check a failed login log. The request should show your real host, not your-api-host.example.com.
Install iOS CocoaPods¶
After ios/ exists and after any native dependency change:
cd ios
pod install
cd ..
Start Metro¶
Metro serves the JavaScript bundle on port 8081 by default.
npx expo start -c
Leave this terminal running. If you see "Metro on 8081 is not running", Metro is not started yet or it crashed.
If port 8081 is already in use:
npx expo start --port 8082 -c
Build and run the native app¶
Metro alone is not enough. You must compile and install the native dev client.
In a second terminal:
npm run ios
Or for Android:
npm run android
These commands compile the native app, install it on the simulator or device, and connect it to Metro.
Two-terminal workflow¶
| Terminal | Command | Purpose |
|---|---|---|
| 1 | npx expo start -c |
Keeps Metro running |
| 2 | npm run ios or npm run android |
Builds and launches the native dev client |
After the first native build, you can reopen the installed app while Metro stays running. Rebuild only when native dependencies change.
Native modules and development builds¶
Libraries with native iOS or Android code are not hot-reloaded into an existing app binary.
When you add or change a native dependency:
- Install with Expo:
npx expo install <package-name>
-
Add any required plugin to
app.config.tsif Expo instructs you to -
Reinstall pods:
cd ios && pod install && cd ..
- Rebuild:
npm run ios
Reloading Metro or refreshing the simulator does not link new native code.
Troubleshooting¶
Cannot find native module 'ExpoSecureStore'¶
The simulator is running an old dev client built before expo-secure-store was linked.
npx expo install expo-secure-store- Confirm
'expo-secure-store'is inpluginsinsideapp.config.ts cd ios && pod install && cd ..- With Metro running,
npm run ios - If needed, delete the Gezen app from the simulator and run
npm run iosagain - Last resort:
npx expo prebuild --clean --platform ios
cd ios && pod install && cd ..
npm run ios
App still calls your-api-host.example.com after editing .env¶
Metro was started before you saved .env, or the old config is cached.
- Stop Metro
- Confirm
.envcontains your real URL - Run
npx expo start -c - Relaunch the app
Network error with the correct backend URL¶
- Confirm the backend is running on the host and port in
.env - Confirm your Mac and backend machine are on the same network
- Test from your Mac:
curl -i http://192.168.10.135:8000/api/auth/token
Replace the host and port with your values.
Metro on 8081 is not running¶
Start Metro before launching the app:
npx expo start -c
pnpm install fails¶
This repository is configured for npm. Use npm install only.
ios/ or Podfile missing¶
Generate the native project:
npx expo prebuild --platform ios
cd ios && pod install && cd ..
Useful scripts¶
npm start # Same as expo start
npm run ios # Build and run iOS dev client
npm run android # Build and run Android dev client
npm run web # Run web target
npm test # Run Jest tests
npm run lint # Run ESLint
What to commit vs keep local¶
| Commit to git | Keep local only |
|---|---|
Source code under app/, components/, hooks/ |
.env |
app.config.ts |
ios/ |
package.json, package-lock.json |
android/ |
.env.example |
node_modules/ |
docs/, README.md, config files |
.expo/ |
Never push .env. It contains backend URLs and Firebase keys. Copy from .env.example on each machine.
Never push ios/ or android/. Generate them with npx expo prebuild after clone.