Skip to main content
Expo provides a streamlined development workflow with fast iteration, instant previews, and powerful debugging tools. This guide covers the complete development cycle from writing code to seeing it run on devices.

Development Cycle Overview

Starting Development

Launch Dev Server

Start the development server with:

What Happens When You Start

1

Metro Bundler Starts

Metro bundler launches on port 8081, ready to transform and bundle your JavaScript
2

Dev Server Starts

HTTP server starts to serve:
  • App manifest (configuration)
  • JavaScript bundles
  • Source maps
  • Assets (images, fonts)
3

QR Code Displayed

Terminal shows QR code and connection options:
4

Ready for Connections

Devices can now connect via:
  • QR code scan
  • Direct URL entry
  • Automatic launch (simulators)

Fast Refresh

Fast Refresh updates your app instantly when you save files, preserving component state.

How Fast Refresh Works

1

File Changes Detected

Watchman detects file modifications
2

Module Transformed

Metro transforms only the changed module
3

Hot Update Sent

Update is sent via WebSocket to connected devices
4

Component Re-renders

React re-renders the component, preserving state

What Gets Preserved

Preserved during Fast Refresh:
  • Component state (useState, useReducer)
  • Navigation state
  • Form inputs
  • Scroll position
Triggers Full Reload:
  • Changes to files outside app/ or src/
  • Native module changes
  • app.json modifications
  • New dependencies installed

Example: Fast Refresh in Action

app/index.tsx
When you edit the <Text> content and save, the change appears instantly without resetting count.

Development Server Features

Interactive Terminal

While the dev server is running, you can:

Developer Menu

Access the developer menu:
  • iOS Simulator: Cmd+D
  • Android Emulator: Cmd+M (Mac) or Ctrl+M (Windows/Linux)
  • Physical Device: Shake the device
  • Terminal: Press m
Menu Options:
  • Reload
  • Debug Remote JS (legacy)
  • Enable Fast Refresh
  • Toggle Element Inspector
  • Toggle Performance Monitor
  • Open React DevTools

Element Inspector

Inspect UI elements in your app:
  1. Open developer menu
  2. Select “Toggle Element Inspector”
  3. Tap any element to see its properties

Performance Monitor

Monitor app performance:
  1. Open developer menu
  2. Select “Toggle Performance Monitor”
  3. View real-time metrics:
    • JS thread FPS
    • UI thread FPS
    • RAM usage
    • Bridge traffic

Metro Bundler

Metro is the JavaScript bundler that powers Expo development.

Metro Configuration

Customize Metro in metro.config.js:
metro.config.js

Metro Commands

Asset Handling

Metro automatically handles: Images:
Fonts:
Other Assets:

Build Types

Development Builds

Development builds include your exact dependencies and allow for custom native code. When to use:
  • Need custom native modules
  • Using libraries not in Expo Go
  • Configuring native project settings
  • Testing production-like behavior
Creating a development build:

Expo Go Builds

Expo Go is a pre-built app with common SDK modules. When to use:
  • Learning Expo
  • Prototyping quickly
  • Only using Expo SDK modules
  • Sharing demos
Limitations:
  • No custom native code
  • Limited to included SDK modules
  • Some libraries incompatible
Expo Go includes these SDK modules:
  • Camera, Location, Sensors
  • FileSystem, SQLite, SecureStore
  • Notifications, Updates
  • Image Picker, Document Picker
  • Video, Audio, AV
  • And 40+ more…
See full list.

Production Builds

Production builds are optimized for app stores.
Optimizations applied:
  • Code minification
  • Dead code elimination
  • Asset optimization
  • Source map generation
  • Bundle splitting

Debugging

React DevTools

Debug React components:
Features:
  • Component tree inspection
  • Props and state viewer
  • Performance profiling
  • Hook debugging

Console Logs

View console output in terminal:
Logs appear in:
  • Terminal (where expo start is running)
  • React DevTools console
  • Browser console (web)

Debugging Native Code

iOS (Xcode):
  1. Open ios/YourApp.xcworkspace in Xcode
  2. Set breakpoints in Swift/Objective-C code
  3. Run from Xcode with debugging
Android (Android Studio):
  1. Open android/ folder in Android Studio
  2. Set breakpoints in Kotlin/Java code
  3. Run with debugger attached

Network Debugging

Inspect network requests:
Use React Native Debugger or Flipper for advanced network inspection.

Environment Configuration

Environment Variables

Use expo-constants for environment-specific config:
app.config.js

Development vs Production

Check environment:

Common Workflows

Adding a New Screen

1

Create file in app/ directory

2

Implement screen

app/profile.tsx
3

Navigate to screen

4

Test on device

Fast Refresh automatically shows the new screen

Installing a New Package

1

Install with expo install

2

Import in your code

3

Use the API

4

Rebuild if needed

If the package has native code not in Expo Go:

Testing on Physical Device

1

Connect to same network

Ensure your device and computer are on the same WiFi
2

Start dev server

3

Scan QR code

  • iOS: Use Camera app
  • Android: Use Expo Go app
4

App loads

Your app opens and connects to the dev server
If scanning doesn’t work:
  1. Try tunnel mode:
  2. Check firewall settings
  3. Use USB connection:
    Then connect via USB debugging

Performance Best Practices

Use React.memo and useMemo to prevent unnecessary re-renders:
Use dynamic imports for screens:
Use optimized image formats and sizes:
Use React DevTools Profiler:

Troubleshooting

Clear cache and restart:
  1. Check for syntax errors
  2. Ensure file is in app/ or src/
  3. Manually reload: Press r in terminal
Check for:
  • JavaScript errors in terminal
  • Missing imports
  • Incorrect file paths
  • Network connectivity issues
Rebuild the app:

Next Steps

Expo Go

Learn about the Expo Go app

Tutorial

Build a complete app

Build & Deploy

Ship your app to production

SDK Reference

Explore all SDK modules