Skip to content

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 expo works 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

# Day-to-day: Metro + web; press i/a to attach the existing native dev binary
task dev:frontend          # Metro for the installed dev binary
task dev:frontend:clear    # Same, with Metro cache wiped

# First run / native dep change / broken build state
task dev:ios               # builds + installs the iOS dev binary on the Simulator
task dev:ios:device        # full prebuild + Pods + Xcode + Metro for a physical iPhone
task dev:ios:device:fast   # re-attach to an already-installed device binary
task dev:android           # builds + installs the Android dev binary on the emulator

Tomoda is a custom-native-modules app (Skia / MapLibre / Reanimated 4 / camera / view-shot etc.). Expo Go cannot run it — Metro always serves the dev client. After the first task dev:ios / task dev:ios:device finishes, daily work is task dev:frontend + pressing i in Metro (or relaunching the dev binary on the phone). Fast Refresh applies JS edits in <1 second; only native dep additions or app.config.js plugin changes need another full build.

The Expo dev server prints a QR code and a key menu:

Key Action
w Open the web build in your default browser
i Attach to the installed iOS dev binary on the Simulator
a Attach to the installed Android dev binary on the 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 tasks:

task build:frontend        # static web export → dist/
task lint:frontend         # expo lint + targeted eslint
task typecheck             # tsc --noEmit across the monorepo
task test                  # full test suite

If you need the raw Expo CLI for a one-off (e.g. expo run:ios for a specific device build), cd frontend && npx expo … always works — Task is the wrapper, not a replacement.

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

  1. Backend running on port 8080 (task dev:backend)
  2. .env set to the matching loopback for your target
  3. npm install complete in frontend/
  4. task dev:frontend running → press w or i (after task dev:ios has installed the dev binary)

If anything misbehaves, clear the Metro cache:

task dev:frontend:clear

Next steps