HomeGuidesReferenceLearn

Configure EAS Build with eas.json

Learn how a project using EAS services is configured with eas.json.


eas.json is the configuration file for EAS CLI and services. It is located at the root of your project next to your package.json. Configuration for EAS Build all belongs under the build key. A minimal eas.json is shown below:

eas.json
{
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal"
    },
    "preview": {
      "distribution": "internal"
    },
    "production": {}
  }
}

Build profiles

A build profile is a named group of configurations that describes the necessary parameters to perform a certain type of build.

The JSON object under the build key can contain multiple build profiles, and you can name these build profiles whatever you like. In the previous example, there are three build profiles: development, preview, and production. However, these could have been named foo, bar, and baz if that is your preference.

To run a build with a specific profile, execute eas build --profile <profile-name>. If you omit the --profile flag, EAS CLI will default to using the profile with the name production, if it exists.

Platform-specific and common options

Inside each build profile, you can specify android and ios fields that contain platform-specific configuration for the build. Fields that are available to both platforms can be provided on the platform-specific configuration object or on the root of the profile.

Sharing configuration between profiles

Build profiles can extend another build profile using the extends key. For example, in the preview profile you may have "extends": "production". This will make the preview profile inherit the configuration of the production profile.

Common use cases

Developers using Expo tools usually end up having three different types of builds: development, preview, and production.

Development builds

These builds include developer tools, and they are never submitted to an app store.

By default, eas build:configure will create a development profile with "developmentClient": true. This indicates that this build depends on expo-dev-client.

The development profile also defaults to "distribution": "internal". This will make it easy to distribute your app directly to physical Android and iOS devices. See Internal distribution for more information.

You may alternatively prefer for your development build to run on an iOS Simulator. To do this, use the following configuration for the development profile:

eas.json
{
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "ios": {
        "simulator": true
      }
    }
    // ...
  }
  // ...
}

If you'd like to create a build for internal distribution and another for the iOS Simulator then you can create another development profile for that build. You might call the profile something like development-simulator and use the above configuration on that profile instead of on development. No such configuration is required to run an Android APK on your device and in an emulator. The same APK will work in both circumstances.

Preview builds

These builds don't include developer tools, they are intended to be installed by your team and other stakeholders, to test out the app in production-like circumstances. In this way, they are similar to production builds; the difference arises in that they are either not signed for distribution on stores (ad hoc or enterprise provisioning on iOS), or are packaged in a way that is not optimal for store deployment (Android APK is best for preview, AAB is best for stores).

A minimal preview profile looks like this:

eas.json
{
  "build": {
    "preview": {
      "distribution": "internal"
    }
    // ...
  }
  // ...
}

Similar to development builds, you can configure your preview build to run on the iOS Simulator or create a variant of your preview profile for that purpose. No such configuration is required to run an Android APK on your device and in an emulator; the same APK will work in both circumstances.

Production builds

These builds are submitted to an app store, for release to the general public or as part of a store-facilitated testing process such as TestFlight.

Production builds must be installed through their respective app stores; they cannot be installed directly on your Android Emulator or device, or iOS Simulator or device. The only exception to this is if you explicitly set "buildType": "apk" for Android on your build profile; however, it is recommended to use AAB when submitting to stores, and this is the default configuration.

A minimal production profile looks like this:

eas.json
{
  "build": {
    "production": {}
    // ...
  }
  // ...
}

Installing multiple builds of the same app on a single device

It's common to have development and production builds installed simultaneously on the same device. See Install app variants on the same device.

Configuring your build tools

Every build depends either implicitly or explicitly on a specific set of versions of related tools that are needed to carry out the build process. These include but are not limited to: Node.js, npm, Yarn, Ruby, Bundler, CocoaPods, Fastlane, Xcode, and Android NDK.

Selecting build tool versions

Versions for the most common build tools can be set on build profiles with fields corresponding to the names of the tools. For example "node":

eas.json
{
  "build": {
    "production": {
      "node": "16.18.0"
    }
    // ...
  }
  // ...
}

It's common to want to share build tool configuration between profiles, and we can use extends for that:

eas.json
{
  "build": {
    "production": {
      "node": "16.13.0"
    },
    "preview": {
      "extends": "production",
      "distribution": "internal"
    },
    "development": {
      "extends": "production",
      "developmentClient": true,
      "distribution": "internal"
    }
    // ...
  }
  // ...
}

Selecting resource class

Resource class is the virtual machine resources configuration (CPU cores, RAM size) EAS Build provides to your jobs. By default, the resource class is set to medium, which is usually sufficient for both small and bigger projects. However, if your project requires a more powerful CPU or bigger memory, or if you want your builds to finish faster, you can switch to large workers.

For more details on resources provided to each class, see android.resourceClass and ios.resourceClass property documentations. To run your build on a worker of a specific resource class, configure this property in your build profile:

eas.json
{
  "build": {
    "production": {
      "ios": {
        "resourceClass": "large"
      },
      "android": {
        "resourceClass": "medium"
      }
    }
    %%placeholder-start%%... %%placeholder-end%%
  }
  %%placeholder-start%%... %%placeholder-end%%
}

Note: Running jobs on a large worker requires a paid EAS plan. Subscribe here.

Selecting a base image

The base image for the build job controls the default versions for a variety of dependencies, such as Node.js, Yarn, and CocoaPods. You can override them using the specific named fields as described in the previous section. However, the image includes specific versions of tools that can't be explicitly set any other way, such as the operating system version and Xcode version.

If you are using the Expo managed workflow, EAS Build will pick the appropriate image to use with a reasonable set of dependencies for the SDK version that you are building for. Otherwise, it is recommended to read about the available images on Build server infrastructure.

Examples

Schema

eas.json
{
  "cli": {
    "version": "SEMVER_RANGE",
    "requireCommit": boolean,
    "appVersionSource": string,
    "promptToConfigurePushNotifications": boolean,
  },
  "build": {
    "BUILD_PROFILE_NAME_1": {
      ...COMMON_OPTIONS,
      "android": {
        ...COMMON_OPTIONS,
        ...ANDROID_OPTIONS
      },
      "ios": {
        ...COMMON_OPTIONS,
        ...IOS_OPTIONS
      }
    },
    "BUILD_PROFILE_NAME_2": {},
	...
  }
}

You can specify common properties both in the platform-specific configuration object or at the profile's root. The platform-specific options take precedence over globally-defined ones.

A managed project with several profiles
eas.json
{
  "build": {
    "base": {
      "node": "12.13.0",
      "yarn": "1.22.5",
      "env": {
        "EXAMPLE_ENV": "example value"
      },
      "android": {
        "image": "default",
        "env": {
          "PLATFORM": "android"
        }
      },
      "ios": {
        "image": "latest",
        "env": {
          "PLATFORM": "ios"
        }
      }
    },
    "development": {
      "extends": "base",
      "developmentClient": true,
      "env": {
        "ENVIRONMENT": "development"
      },
      "android": {
        "distribution": "internal",
        "withoutCredentials": true
      },
      "ios": {
        "simulator": true
      }
    },
    "staging": {
      "extends": "base",
      "env": {
        "ENVIRONMENT": "staging"
      },
      "distribution": "internal",
      "android": {
        "buildType": "apk"
      }
    },
    "production": {
      "extends": "base",
      "env": {
        "ENVIRONMENT": "production"
      }
    }
  }
}
A bare project with several profiles
eas.json
{
  "build": {
    "base": {
      "env": {
        "EXAMPLE_ENV": "example value"
      },
      "android": {
        "image": "ubuntu-18.04-android-30-ndk-r19c",
        "ndk": "21.4.7075529"
      },
      "ios": {
        "image": "latest",
        "node": "12.13.0",
        "yarn": "1.22.5"
      }
    },
    "development": {
      "extends": "base",
      "env": {
        "ENVIRONMENT": "staging"
      },
      "android": {
        "distribution": "internal",
        "withoutCredentials": true,
        "gradleCommand": ":app:assembleDebug"
      },
      "ios": {
        "simulator": true,
        "buildConfiguration": "Debug"
      }
    },
    "staging": {
      "extends": "base",
      "env": {
        "ENVIRONMENT": "staging"
      },
      "distribution": "internal",
      "android": {
        "gradleCommand": ":app:assembleRelease"
      }
    },
    "production": {
      "extends": "base",
      "env": {
        "ENVIRONMENT": "production"
      }
    }
  }
}

Environment variables

You can configure environment variables on your build profiles using the "env" field. These environment variables will be used to evaluate app.config.js locally when you run eas build, and they will also be set on the EAS Build builder.

eas.json
{
  "build": {
    "production": {
      "node": "16.13.0",
      "env": {
        "API_URL": "https://company.com/api"
      }
    },
    "preview": {
      "extends": "production",
      "distribution": "internal",
      "env": {
        "API_URL": "https://staging.company.com/api"
      }
    }
    // ...
  }
  // ...
}

The Environment variables and secrets reference explains this topic in greater detail, and the updates guide provides guidance on considerations when using this feature alongside expo-updates.

Next step

EAS Build schema reference

See complete reference of available properties for EAS Build.