Local Development Guide

Standard workflow for building and running apps locally on simulators and devices. Follow this for every new app created from the boilerplate.

First-Time Setup (New App)

1. Install dependencies

npm install

2. Set up assets

# Copy icon
cp assets/source/icon-source.png assets/icon.png
cp assets/source/icon-source.png assets/adaptive-icon.png

# Copy splash
cp assets/source/splash-logo.png assets/splash.png

# Generate favicon
cp assets/icon.png assets/favicon.png && sips -z 48 48 assets/favicon.png

3. Generate native projects

npx expo prebuild --clean
You MUST run prebuild before the first build. This generates the ios/ and android/ folders with all native modules properly linked.

4. Install iOS pods

cd ios && pod install && cd ..

5. Build and run

# iOS Simulator
npx expo run:ios

# Android Emulator
npx expo run:android

# Specific iOS simulator
npx expo run:ios --device "iPhone 16 Pro"

Common Error: "Cannot find native module"

[Error: Cannot find native module 'ExpoSecureStore']
[Error: The package 'react-native-keyboard-controller' doesn't seem to be linked]

Cause: The ios/ folder is stale — native modules were added but the native project wasn't regenerated.

npx expo prebuild --clean
npx expo run:ios

Development Workflow

Starting the dev server

# Standard
npx expo start

# Clear Metro cache (if you see stale bundle errors)
npx expo start --clear

# Force dev client mode (not Expo Go)
npx expo start --dev-client

After adding native dependencies

npm install <package>
npx expo prebuild --clean
npx expo run:ios

Nuclear clean build

rm -rf node_modules ios android
npm install
npx expo prebuild --clean
npx expo run:ios

API Routes — Local Dev Server

Expo API routes (src/app/api/) only work when deployed via EAS. For local simulator testing, use the included dev-server.js.

Setup

.env
OPENAI_API_KEY=sk-your-key
EXPO_PUBLIC_API_URL=http://YOUR_LOCAL_IP:8082
# Install dotenv
npm install dotenv --save-dev

# Find your local IP
ifconfig en0 | grep "inet " | awk '{print $2}'

Running the dev server

# Terminal 1: Start dev server
node dev-server.js

# Terminal 2: Start Metro
npx expo start --clear

# Terminal 3: Run on simulator
npx expo run:ios

The dev server logs all API calls so you can debug issues. In production, API routes run automatically on EAS — no dev-server needed.

Simulator Screenshots (for App Store)

# Set clean status bar
xcrun simctl status_bar booted override \
  --time "9:41" \
  --batteryState charged \
  --batteryLevel 100 \
  --wiFiMode active \
  --wiFiBars 3 \
  --cellularMode active \
  --cellularBars 4

# Capture screenshot
xcrun simctl io booted screenshot ~/Desktop/screenshot.png

Production EAS Deployment

Set API keys on EAS (one time per project)

API keys for EAS Hosting (API routes) must be PLAINTEXT, not SECRET. Secrets are only available during native builds, not at runtime in the deployed worker.
# PLAINTEXT — readable by deployed API routes at runtime
eas env:create --name OPENAI_API_KEY --value sk-xxx --visibility plaintext --environment production
eas env:create --name ANTHROPIC_API_KEY --value sk-ant-xxx --visibility plaintext --environment production

Deploy API routes (required before first production test)

# Export and deploy API routes to EAS Hosting
npx expo export --platform web
eas deploy --prod --environment production

# Verify
curl https://your-app.expo.app/api/health
After deploying, you can set EXPO_PUBLIC_API_URL=https://your-app.expo.app in your local .env so dev builds can reach the production API routes directly — no need for dev-server.js.

Build and submit

# Production iOS build (sends to TestFlight)
eas build --platform ios --profile production

# Production Android build (AAB for Play Store)
eas build --platform android --profile production

# Submit to App Store
eas submit --platform ios

Troubleshooting

ProblemFix
"Cannot find native module"npx expo prebuild --clean && npx expo run:ios
Metro bundler stucknpx expo start --clear
Pod install failscd ios && rm -rf Pods Podfile.lock && pod install
Xcode build failsOpen ios/*.xcworkspace in Xcode, clean build (Cmd+Shift+K)
White screen on launchCheck Metro console for JS errors
Old bundle loadingKill the app, clear Metro cache, restart
dev-server.js Included

Test AI routes on simulator instantly

Local dev server bridges the Expo API Routes gap — no EAS needed for testing.

dev-server.js included
Full API logging
Zero config switch to EAS
Get ShipReactNative
Save 40+ hours of setup