Skip to main content

System Requirements

Required Tools

  • Node.js: Version specified in .nvmrc (currently 20.x)
  • npm: Comes with Node.js
  • Git: For version control
  • nvm: Recommended for Node version management
  • watchman: Required for React Native development

Platform-Specific Requirements

  • macOS: Required for iOS development
  • Windows/Linux: Can develop for Android and Web
  • All Platforms: Can develop for Web

General Setup

1. Install nvm

macOS/Linux

# Install nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash

# Reload shell configuration
source ~/.bashrc  # or ~/.zshrc for zsh

# Verify installation
nvm --version

Windows

Use nvm-windows.

2. Install Node.js and npm

# From the project directory
nvm install

# Verify installation
node --version
npm --version

3. Install Watchman

macOS

brew install watchman

Linux

# Ubuntu/Debian
sudo apt-get install watchman

# Or build from source
# See: https://facebook.github.io/watchman/docs/install.html

Windows

Not required for Windows development.

4. Clone Repository

# Clone the repo
git clone https://github.com/Expensify/App.git
cd App

# Install dependencies
npm install

Web Development

Setup

No additional setup required beyond general setup.

Running the Web App

npm run web
The app will be available at http://localhost:8080.

External Contributors

Set this environment variable to avoid CORS errors:
# Create .env file
echo "USE_WEB_PROXY=true" > .env

# Run the app
npm run web

Troubleshooting Web

CORS Errors

Access to fetch at 'https://www.expensify.com/api/BeginSignIn' 
from origin 'http://localhost:8080' has been blocked by CORS policy
Solution: Remove .env file or set USE_WEB_PROXY=true.

Port Already in Use

# Kill process on port 8080
lsof -ti:8080 | xargs kill -9

# Or use a different port
PORT=8081 npm run web

iOS Development

macOS only: iOS development requires macOS and Xcode.

Prerequisites

  1. Xcode: Install from App Store (latest stable version)
  2. Xcode Command Line Tools:
    xcode-select --install
    
  3. CocoaPods: Install Ruby dependencies
    sudo gem install cocoapods
    

Setup

# Install iOS dependencies
cd ios
pod install
cd ..

Running on iOS Simulator

npm run ios

# Or specify a device
npm run ios -- --simulator="iPhone 15 Pro"

Running on Physical Device

See HOW_TO_BUILD_APP_ON_PHYSICAL_IOS_DEVICE.md.

Troubleshooting iOS

Pod Install Fails

# Clean pod cache
cd ios
pod deintegrate
pod install --repo-update
cd ..

Build Fails

# Clean build
cd ios
xcodebuild clean
cd ..

# Remove derived data
rm -rf ~/Library/Developer/Xcode/DerivedData

# Reinstall dependencies
npm run clean
npm install
cd ios && pod install && cd ..

Simulator Not Opening

# Reset simulator
xcrun simctl erase all

# Or open Xcode and reset from menu:
# Device > Erase All Content and Settings

Android Development

Prerequisites

  1. Java Development Kit (JDK)
    # macOS
    brew install openjdk@17
    
    # Ubuntu/Linux
    sudo apt-get install openjdk-17-jdk
    
  2. Android Studio
    • Download from developer.android.com
    • Install with default settings
    • Open Android Studio and complete initial setup
  3. Android SDK
    • Open Android Studio > Settings > Appearance & Behavior > System Settings > Android SDK
    • Install:
      • Android SDK Platform 34
      • Android SDK Build-Tools 34.0.0
      • Android SDK Command-line Tools

Environment Variables

Add to .bashrc, .zshrc, or .bash_profile:
export ANDROID_HOME=$HOME/Library/Android/sdk  # macOS
# or
export ANDROID_HOME=$HOME/Android/Sdk  # Linux

export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/platform-tools
Reload shell:
source ~/.bashrc  # or ~/.zshrc

Create Android Virtual Device (AVD)

  1. Open Android Studio
  2. Tools > Device Manager
  3. Create Virtual Device
  4. Select a device (e.g., Pixel 6)
  5. Select system image (API 34 recommended)
  6. Finish setup

Running on Android Emulator

# Start emulator (from Android Studio or command line)
emulator -avd Pixel_6_API_34 &

# Run app
npm run android

Running on Physical Device

  1. Enable Developer Options on your device
  2. Enable USB Debugging
  3. Connect device via USB
  4. Verify connection:
    adb devices
    
  5. Run app:
    npm run android
    

Troubleshooting Android

Build Fails

# Clean gradle build
cd android
./gradlew clean
cd ..

# Clear metro cache
npm start -- --reset-cache

ADB Offline

adb kill-server
adb start-server
adb devices

Emulator Not Starting

# List available AVDs
emulator -list-avds

# Start specific AVD
emulator -avd <avd_name>

# Cold boot (slower but more reliable)
emulator -avd <avd_name> -no-snapshot-load

Port Already in Use

# Kill metro bundler
lsof -ti:8081 | xargs kill -9

# Restart
npm start

macOS Desktop Development

Prerequisites

Same as iOS development requirements.

Running macOS App

npm run macos

Testing on All Platforms

Required: All changes must be tested on iOS, Android, Web, and mWeb before submitting a PR.

Testing Without Mac

If you don’t have a Mac, see TESTING_MACOS_AND_IOS.md for alternatives:
  • Cloud-based Mac services
  • MacinCloud
  • CI/CD preview builds

Testing Mobile Web (mWeb)

Use browser DevTools to simulate mobile:
  1. Open http://localhost:8080 in Chrome
  2. Open DevTools (F12)
  3. Click device toggle icon (Cmd+Shift+M / Ctrl+Shift+M)
  4. Select mobile device (e.g., iPhone 12 Pro)
  5. Test the app

IDE Setup

// .vscode/extensions.json
{
  "recommendations": [
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode",
    "bradlc.vscode-tailwindcss",
    "ms-vscode.vscode-typescript-next"
  ]
}

Settings

// .vscode/settings.json
{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact"
  ],
  "typescript.tsdk": "node_modules/typescript/lib"
}

IntelliJ IDEA / WebStorm

  1. Settings > Languages & Frameworks > JavaScript > Prettier
  2. Check “On save”
  3. Set Prettier package: <project>/node_modules/prettier

Environment Variables

Common Variables

# .env (optional - not recommended for external contributors)
NEW_EXPENSIFY_URL=https://dev.new.expensify.com
SECURE_EXPENSIFY_URL=https://www.expensify.com/api
EXPENSIFY_URL=https://www.expensify.com
USE_WEB_PROXY=true  # External contributors should set this
Creating .env is not recommended for external contributors. Variables can become outdated and cause errors.

Testing Specific Features

# Enable Redux DevTools for Onyx debugging
USE_REDUX_DEVTOOLS=true

# Enable Why Did You Render for performance debugging
USE_WDYR=true

# Capture performance metrics
CAPTURE_METRICS=true
ONYX_METRICS=true

Development Workflow

1. Start Development Server

# Terminal 1: Metro bundler (for React Native)
npm start

# Terminal 2: Run platform
npm run web     # or ios/android

2. Make Changes

Edit files in src/. Changes will hot-reload automatically.

3. Run Code Quality Checks

# Format code (REQUIRED before commit)
npm run prettier

# Lint
npm run lint

# Type check (fast, development)
npm run typecheck-tsgo

# Type check (production gate)
npm run typecheck

# Run all checks
npm run prettier && npm run lint && npm run typecheck

4. Run Tests

# Run all tests
npm test

# Run specific test file
npm test -- MyComponent.test.tsx

# Run tests in watch mode
npm test -- --watch

5. Clean and Reset

If things aren’t working:
# Clean everything
npm run clean

# Reinstall dependencies
npm install

# iOS: Reinstall pods
cd ios && pod install && cd ..

# Android: Clean gradle
cd android && ./gradlew clean && cd ..

# Clear React Native cache
npm start -- --reset-cache

# Nuclear option: Delete everything and start over
rm -rf node_modules ios/Pods ios/Podfile.lock
npm install
cd ios && pod install && cd ..

Debugging

React DevTools

# Install globally
npm install -g react-devtools

# Run
react-devtools

# In app, shake device (or Cmd+D) > "Toggle Inspector"

Flipper

Flipper is installed automatically with React Native:
  1. Download Flipper Desktop
  2. Run app in development mode
  3. Flipper auto-detects the app
  4. View logs, network, layout, Onyx state, etc.

Chrome DevTools (Web)

  1. Open http://localhost:8080 in Chrome
  2. Open DevTools (F12)
  3. Debug like a normal web app

Safari DevTools (iOS)

  1. Enable Web Inspector on iOS device:
    • Settings > Safari > Advanced > Web Inspector
  2. Run app on device or simulator
  3. Open Safari on Mac > Develop > [Device] > [App]

Performance Testing

Reassure Performance Tests

# Run performance tests
npm run test:perf

# Compare with baseline
npm run test:perf -- --compare
See REASSURE_PERFORMANCE_TEST.md.

Common Issues

Metro Bundler Port Conflict

# Kill process on port 8081
lsof -ti:8081 | xargs kill -9

# Restart metro
npm start

Node Version Mismatch

# Check current version
node --version

# Use correct version
nvm use

# Install if missing
nvm install

Pod Install Fails (iOS)

cd ios
rm -rf Pods Podfile.lock
pod install --repo-update
cd ..

Gradle Sync Fails (Android)

cd android
./gradlew clean
cd ..
rm -rf android/.gradle
npm run android

Next Steps

Coding Standards

Learn the coding standards and best practices

Testing

Write and run tests

Pull Requests

Submit your first PR

Architecture

Understand the architecture

Additional Resources

Build docs developers (and LLMs) love