Setup¶
Get the Tomoda frontend running on your machine for iOS, Android, and web.
Prerequisites¶
- Node.js 18+ (Expo SDK 55 baseline) and npm
- Git
- For iOS: Xcode 15+ with Command Line Tools and an iOS Simulator
- For Android: see the dedicated Android Setup page (JDK 17, Android Studio, SDK, emulator)
- (Optional) Expo CLI globally — not required;
npx expoworks fine
Expo Go vs. dev client
Tomoda has native dependencies (Google Maps, Google Sign-In, Apple Sign-In, Passkeys), so you cannot run it in plain Expo Go. Use npx expo run:ios / npx expo run:android to build a dev client, or run on web with npm run web.
Install¶
From the repo root:
# Either invoke the Task runner...
task deps:frontend
# ...or install directly
cd frontend
npm install
task deps:frontend is defined in Taskfile.yml and simply runs npm install inside frontend/.
Run¶
# From repo root
task dev:frontend
# Or directly
cd frontend
npm run dev # alias for `expo start`
The Expo dev server prints a QR code and a key menu:
| Key | Action |
|---|---|
w |
Open the web build in your default browser |
i |
Launch the iOS Simulator |
a |
Launch the configured Android emulator |
r |
Reload the app |
j |
Open the JS debugger |
You can also scan the QR with your phone if you have a development build installed.
Other scripts (frontend/package.json):
npm run web # expo start --web
npm run ios # expo run:ios (native build)
npm run android # expo run:android (native build)
npm run build # static web export → dist/
npm run lint # expo lint + targeted eslint
npm run typecheck # tsc --noEmit
npm test # jest
Environment variables¶
The app reads two public env vars (Expo only exposes vars prefixed with EXPO_PUBLIC_):
| Variable | Purpose | Default |
|---|---|---|
EXPO_PUBLIC_API_URL |
REST base URL ({host}/api/v1) |
http://127.0.0.1:8080/api/v1 |
EXPO_PUBLIC_WS_URL |
WebSocket base URL | ws://127.0.0.1:8080/ws |
EXPO_PUBLIC_WEB_URL |
Public web origin (used for share links) | https://tomoda.life |
In production the values are baked into eas.json under the production profile:
"production": {
"env": {
"EXPO_PUBLIC_API_URL": "https://api.tomoda.life/api/v1",
"EXPO_PUBLIC_WS_URL": "wss://api.tomoda.life/ws"
}
}
Locally, drop them in frontend/.env (read by dotenv via app.config.js):
EXPO_PUBLIC_API_URL=http://127.0.0.1:8080/api/v1
EXPO_PUBLIC_WS_URL=ws://127.0.0.1:8080/ws
How the app finds the backend in dev¶
Expo Go and dev clients on different runtimes resolve localhost differently. Use the right loopback address for each target:
| Target | Loopback to use |
|---|---|
| Web (browser) | 127.0.0.1 or localhost |
| iOS Simulator | 127.0.0.1 |
| Android Emulator | 10.0.2.2 (special host route inside the AVD) |
| Physical device on LAN | Your Mac's LAN IP (e.g. 192.168.1.42) |
Android emulator + localhost
From the Android emulator, localhost resolves to the emulator itself, not the host machine. Always use 10.0.2.2 to reach the backend running on your Mac. If login fails immediately on Android, this is almost always the cause — see Android Setup.
First run checklist¶
- Backend running on port
8080(task dev:backend) .envset to the matching loopback for your targetnpm installcompletenpm run devrunning → pressw,i, ora
If anything misbehaves, clear the Metro cache:
rm -rf $TMPDIR/metro-*
npx expo start --clear
Next steps¶
- Architecture — how the codebase is laid out
- Routing — Expo Router and the route tree
- State Management — the nine context providers