Skip to main content

Building Standalone Apps

Standalone apps are self-contained native applications that can be distributed through app stores or other channels. This guide covers both cloud-based builds with EAS Build and local compilation.

Understanding Build Types

Expo supports two primary approaches to creating standalone builds: EAS Build is a cloud-based build service that compiles your app on remote servers. Benefits include:
  • No need to install Android Studio or Xcode locally
  • Consistent build environment across team members
  • Handles code signing automatically
  • Build from any operating system (Windows, Linux, macOS)
  • Integrated with EAS Submit for streamlined app store deployment

Local Builds

Local builds compile your app on your own machine. Use this when:
  • Company policies restrict use of third-party CI/CD services
  • You need to debug build failures in detail
  • You want complete control over the build environment

Building with EAS Build

1

Install and Configure EAS CLI

npm install -g eas-cli
eas login
Configure your project for EAS Build:
eas build:configure
This creates an eas.json file with default build profiles:
eas.json
{
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal"
    },
    "preview": {
      "distribution": "internal"
    },
    "production": {}
  }
}
2

Configure App Identifiers

Set your bundle identifiers in app.json:
app.json
{
  "expo": {
    "name": "My App",
    "slug": "my-app",
    "version": "1.0.0",
    "ios": {
      "bundleIdentifier": "com.yourcompany.yourapp"
    },
    "android": {
      "package": "com.yourcompany.yourapp"
    }
  }
}
3

Create Production Builds

eas build --platform android --profile production
This creates an AAB (Android App Bundle) by default, which is required for Google Play Store submissions.
4

Monitor Build Progress

EAS CLI displays a link to monitor your build:
✔ Build started, it may take a few minutes to complete.
  https://expo.dev/accounts/yourname/projects/yourapp/builds/abc123
You can also view all builds:
eas build:list

Local Build Configuration

Local builds require Android Studio (for Android) and Xcode (for iOS) to be installed and properly configured on your machine.

Running EAS Build Locally

You can run the same EAS Build process locally:
eas build --platform android --local
eas build --platform ios --local
This replicates the cloud build environment on your machine. Environment Variables for Debugging:
# Keep build artifacts after build completes
export EAS_LOCAL_BUILD_SKIP_CLEANUP=1

# Specify custom working directory
export EAS_LOCAL_BUILD_WORKINGDIR=/path/to/build/dir

# Custom artifacts output directory
export EAS_LOCAL_BUILD_ARTIFACTS_DIR=./builds

eas build --platform android --local

Building with Native Tools

For complete control, you can use native build tools directly.
Step 1: Generate Native ProjectsIf using Continuous Native Generation:
npx expo prebuild --platform android
Step 2: Build with Gradle
cd android
./gradlew assembleRelease  # For APK
./gradlew bundleRelease    # For AAB (Play Store)
Output locations:
  • APK: android/app/build/outputs/apk/release/app-release.apk
  • AAB: android/app/build/outputs/bundle/release/app-release.aab

Build Profiles

Customize builds for different scenarios using profiles in eas.json:
eas.json
{
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "android": {
        "buildType": "apk"
      },
      "ios": {
        "simulator": true
      }
    },
    "preview": {
      "distribution": "internal",
      "channel": "preview"
    },
    "production": {
      "channel": "production",
      "android": {
        "buildType": "app-bundle"
      }
    },
    "staging": {
      "extends": "production",
      "channel": "staging",
      "env": {
        "API_URL": "https://staging-api.example.com"
      }
    }
  }
}

Build Profile Options

Common Options:
  • distribution: "store" | "internal" - Determines build artifacts
  • channel: EAS Update channel name for OTA updates
  • env: Environment variables available during build
  • credentialsSource: "remote" | "local" - Where to get signing credentials
Android Options:
  • buildType: "apk" | "app-bundle" - Output format
  • gradleCommand: Custom Gradle command
  • image: Build image version (e.g., "sdk-54")
iOS Options:
  • simulator: Build for simulator (development only)
  • buildConfiguration: "Debug" | "Release"
  • scheme: Xcode scheme to build

Build Output Types

Android Build Types

AAB (Android App Bundle) - Recommended for Store
{
  "android": {
    "buildType": "app-bundle"
  }
}
  • Required by Google Play Store (for new apps since August 2021)
  • Smaller download size for users
  • Cannot be installed directly on devices
APK (Android Package) - For Testing
{
  "android": {
    "buildType": "apk"
  }
}
  • Can be installed directly on devices
  • Useful for internal distribution
  • Larger file size than AAB

iOS Build Types

App Store Distribution
{
  "ios": {
    "simulator": false
  }
}
  • For App Store submission
  • Requires distribution certificate
  • Works on physical devices only
Simulator Build (Development)
{
  "ios": {
    "simulator": true
  }
}
  • Runs on iOS Simulator
  • Faster build times
  • No code signing required
  • Cannot run on physical devices

Advanced Build Options

Auto-Increment Version

eas.json
{
  "build": {
    "production": {
      "android": {
        "autoIncrement": "versionCode"
      },
      "ios": {
        "autoIncrement": "buildNumber"
      }
    }
  }
}

Custom Build Scripts

Run custom scripts during the build process using eas-build-pre-install and eas-build-post-install hooks in package.json:
package.json
{
  "scripts": {
    "eas-build-pre-install": "echo 'Running before dependencies install'",
    "eas-build-post-install": "node scripts/post-install.js"
  }
}

Resource Classes

For larger apps, use more powerful build machines:
eas.json
{
  "build": {
    "production": {
      "android": {
        "resourceClass": "large"  // default | medium | large
      },
      "ios": {
        "resourceClass": "large"  // default | medium | large
      }
    }
  }
}

Troubleshooting

Build Failed with Out of Memory

Increase resource class or enable Hermes (Android):
app.json
{
  "expo": {
    "android": {
      "enableHermes": true
    }
  }
}

iOS Build Fails with Provisioning Profile Issues

Clear credentials and regenerate:
eas credentials --platform ios
# Select "Remove all credentials"
eas build --platform ios --clear-cache

Android Build Fails with Gradle Errors

Clear build cache:
eas build --platform android --clear-cache

Viewing Detailed Build Logs

  1. Click the build URL from EAS CLI output
  2. Navigate to the “Logs” tab
  3. Download full logs for offline analysis
For local builds, check the working directory:
export EAS_LOCAL_BUILD_SKIP_CLEANUP=1
eas build --platform android --local
# Logs will be in the working directory

Next Steps