## Intro

Expo commands are the daily drivers for React Native developers, DevOps engineers, and technical startup teams who need to move from an observed problem to a verified result without guessing. This guide focuses on the commands you will actually run: checking your environment, creating and starting projects, building binaries, diagnosing issues, and recovering from failures. Every command includes prerequisites, a concrete example with placeholders, the expected output, a failure signal, and a recovery path.

The goal is operational safety. Observe before changing, limit the blast radius, use placeholders instead of secrets, verify the result, and document how to recover if the expected state is not reached. Whether you are onboarding a new teammate or debugging a CI pipeline, this guide gives you the exact commands and their real-world context.

## Version and Environment Inventory

Before running any Expo command, you need a clear snapshot of your environment. The first command is always npx expo --version . This read-only check tells you which Expo CLI version is installed and whether your Node.js version meets the requirements. Expected output example:

7.0.3

If you see an error like npx: command not found , Node.js is missing or not in PATH. Install Node.js 18 or newer from the official website, then verify with node --version (expected: v18.16.0 or higher) and npm --version (expected: 9.5.1 or higher).

For a full diagnostic, run npx expo-doctor . This command checks for common misconfigurations such as incompatible package versions, missing dependencies, and issues with app.json. Expected output example:

All checks passed

If expo-doctor reports errors, fix each reported item one at a time. For example, if it says package.json: The following packages are not compatible with Expo SDK 49 , update the listed packages with npx expo install <package-name> and rerun expo-doctor until it passes.

To capture the current state for troubleshooting, save the output of these commands to a file with timestamps:

npx expo --version > expo-env-$(date +%Y%m%d-%H%M).txt && npx expo-doctor >> expo-env-$(date +%Y%m%d-%H%M).txt

This gives you an auditable snapshot before any change. Never include real credentials or tokens in these logs.

## Project Initialization and Start

The most common workflow is creating a new Expo project and starting the development server. Use npx create-expo-app with a clear project name:

npx create-expo-app my-app --template blank

This command scaffolds a minimal project. Expected output ends with Project ready! and instructions to run cd my-app and npx expo start . If the command fails with a network error, check your npm registry access and retry with --registry https://registry.npmjs.org .

To start the development server, navigate into the project directory and run:

npx expo start

Expected output shows a QR code and a list of options (press a for Android, i for iOS, w for web). On a physical device, install Expo Go from the app store, scan the QR code, and your project loads. If the QR code does not appear, the server may be unable to bind to the port; try npx expo start --port 8082 and scan the updated QR code.

For CI or headless environments, start without the interactive UI:

npx expo start --no-dev --minify

This runs a production-like server. Verify it is running by checking the terminal output for Metro waiting on http://localhost:8081 .

## Configuration and Safe Changes

Expo configuration lives in app.json and package.json . Before editing, back up the current file and note the change you intend to make. Example:

cp app.json app.json.bak

A common safe change is setting the app name and slug. In app.json , update the name and slug fields to match your project:

{
 "expo": {
 "name": "MyApp",
 "slug": "my-app",
 "version": "1.0.0",
 "orientation": "portrait",
 "icon": "./assets/icon.png",
 "userInterfaceStyle": "light",
 "splash": {
 "image": "./assets/splash.png",
 "resizeMode": "contain",
 "backgroundColor": "#ffffff"
 },
 "assetBundlePatterns": [
 "**/*"
 ],
 "ios": {
 "supportsTablet": true
 },
 "android": {
 "adaptiveIcon": {
 "foregroundImage": "./assets/adaptive-icon.png",
 "backgroundColor": "#ffffff"
 }
 },
 "web": {
 "favicon": "./assets/favicon.png"
 }
 }
} 
 After editing, validate the configuration with npx expo config --type public . This prints the resolved configuration and catches syntax errors. Expected output is a JSON object without errors. If you see Error parsing app.json , recheck your JSON syntax, then restore from backup if needed with cp app.json.bak app.json .

For environment-specific values, use app.config.js and environment variables. Example:

module.exports = {
 expo: {
 name: process.env.APP_NAME || 'MyApp',
 slug: 'my-app',
 extra: {
 apiUrl: process.env.API_URL || 'https://api.example.com',
 },
 },
}; 
 Run with API_URL=https://staging.example.com npx expo start and verify by logging Constants.expoConfig.extra.apiUrl in your app. Never hardcode production secrets.

## Building and Publishing

For test builds, use Expo Application Services (EAS) with eas build . First install EAS CLI:

npm install -g eas-cli

Then log in and configure:

eas login eas build:configure

The configure command creates eas.json with default build profiles. To create an Android APK for testing:

eas build -p android --profile preview

Expected output: EAS starts a build on the cloud and provides a URL to monitor progress. The build typically takes 10-20 minutes. You receive a download link when it finishes. Failure signals include missing credentials or invalid app configuration. To recover, run eas build:configure again and ensure your app.json is valid.

For a production build, use the production profile with version bump:

eas build -p android --profile production --auto-submit

This triggers a build and submission to the Play Store if configured. Always test the preview build first.

To publish an over-the-air update without a full build, use expo publish (legacy) or eas update :

eas update --branch production --message "Fix crash on login"

Expected output shows the update URL and group ID. Users with Expo Go or a development build receive the update on next launch. If the update fails, check your branch name and ensure the project is linked to EAS.

## Verification and Diagnostics

After starting the server or making changes, verify your app loads and functions. Use the Metro bundler logs to confirm the bundle was created. Expected output in the terminal:

iOS Bundled 1234ms or Android Bundled 987ms

If you see a red screen in Expo Go, the error is often a JavaScript runtime error. Open the terminal running expo start to read the stack trace. For example, Error: Cannot find module './screens/Home' means the file path is incorrect. Fix the import and the app reloads automatically.

To diagnose network issues between your device and development server, run npx expo start --tunnel . This creates a tunnel that works on restricted networks. Expected output shows a new URL and QR code. If the tunnel fails, install @expo/ngrok globally and retry.

For a detailed dependency check, run npx expo install --check . This compares your package.json dependencies with the versions recommended for your Expo SDK. If mismatches are found, it lists them; fix by running npx expo install <package> for each. Example output:

The following packages should be updated: expo@49.0.0 -> 49.0.10

Run npx expo install expo to update to the compatible version.

## Failure Modes and Recovery

Every Expo command can fail, and knowing the recovery steps saves time. Common failure modes and their fixes:

Port already in use : Running npx expo start shows Error: listen EADDRINUSE: address already in use :::8081 . Kill the process using the port with lsof -ti:8081 | xargs kill -9 (on macOS/Linux) or use a different port: npx expo start --port 8082 .

Metro cache corruption : If the bundler hangs or fails to resolve modules, clear the cache with npx expo start -c . This restarts Metro with a clean cache. Expected output: the bundler starts and compiles without stale module errors.

Dependency mismatch : If expo start throws an error like The package 'expo' is not installed in this project , run npx expo install to install all missing compatible dependencies. Verify with npx expo-doctor .

Authentication failure with EAS : Running eas build shows Not logged in . Run eas login with your Expo account, then verify with eas whoami (expected output: your username).

Build failure due to missing secrets : If the build fails with Environment variable X is not set , add the variable in EAS dashboard under Environment Variables, then rebuild with eas build -p android --profile preview --clear-cache .

App crashing on startup : If Expo Go shows a red error screen, capture the error text, search for the stack trace, and fix the JavaScript error. If it is a native module issue, you may need to create a development build with npx expo run:android instead of using Expo Go.

For each failure, document the observed error, the command run, and the step that fixed it. Keep a personal or team runbook with these entries to speed up future recovery.

## Operations Checklist

Use this checklist before and after each Expo operation to ensure consistency and safety.

Before any change

- Check environment: npx expo --version and npx expo-doctor . Ensure both pass.

- Back up configuration: cp app.json app.json.bak .

- Identify the exact command and its expected outcome.

- Verify no secrets are hardcoded in files to be modified.

During the operation

- Run one command at a time.

- Capture output to a log: npx expo start > expo-start.log 2>&1 .

- Watch for expected success signals, such as Metro waiting on http://localhost:8081 .

After the operation

- Verify the app loads on the target platform.

- Run npx expo-doctor again to confirm no regressions.

- If the change failed, restore from backup: cp app.json.bak app.json .

- Document the result in your runbook.

For CI/CD integration, create script steps:

# .gitlab-ci.yml example
expo-check:
 stage: test
 script:
 - npm install
 - npx expo-doctor
 - npx expo export --platform web --output-dir dist 
 This ensures every merge request passes Expo health checks and can produce a web build.

## Conclusion

Expo basic commands become safe operations only when you version-scope them, observe before changing, and verify every result. A command without its expected output and failure mode is a guess, not a procedure. Use the environment inventory to establish a baseline, start and configure projects with backups, build with proper profiles, diagnose with logs, and recover with documented steps.

Start with one low-risk verification in your current project: run npx expo-doctor and npx expo start -c , record the outputs, and confirm your app loads. Then apply the same discipline to each build, update, and configuration change. The result is a reproducible Expo workflow that makes failures visible, keeps sensitive values protected, and gets your team back to building features faster.