Skip to main content
Glama
app-versions.md10.1 kB
--- title: App version management description: Learn about different version types and how to manage them remotely or locally. hasVideoLink: true --- Android and iOS each expose two values to identify the version of an app: the version visible in stores (user-facing version) and the version visible only to developers (developer-facing build version). This guide explains how you can manage those versions remotely or locally. ## App versions In Expo projects, the following properties can be used to define app versions in the [app config](/workflow/configuration/) file. | Property | Description | | ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [`version` ](/versions/latest/config/app/#version) | The user-facing version visible in stores. On Android, it represents `versionName` name in **android/app/build.gradle**. On iOS, it represents `CFBundleShortVersionString` in **Info.plist**. | | [`android.versionCode`](/versions/latest/config/app/#versioncode) | The developer-facing build version for Android. It represents `versionCode` in **android/app/build.gradle**. | | [`ios.buildNumber`](/versions/latest/config/app/#buildnumber) | The developer-facing build version for iOS. It represents `CFBundleVersion` in **Info.plist**. | ### Using app versions in your app To show the user-facing version inside your app, you can use [`Application.nativeApplicationVersion`](/versions/latest/sdk/application/#applicationnativeapplicationversion) from the `expo-application` library. To show the developer-facing build version inside your app, you can use [`Application.nativeBuildVersion`](/versions/latest/sdk/application/#applicationnativebuildversion) from the `expo-application` library. ## Recommended workflow ### User-facing version When you are doing a production release, the user-facing version should be explicitly set and updated by you. You can update the `version` property in app config when production build is submitted to the app stores. This also applies if your project uses `expo-updates` with an automatic runtime version policy. This marks the beginning of a new development cycle for a new version of your app. Learn more about [deployment patterns](/eas-update/deployment-patterns). ### Developer-facing build version For developer-facing build version, you can set them to autoincrement on every build. This will help you avoid making manual changes to the project every time you upload a new archive on Play Store testing channels or TestFlight. One common cause for app store rejections is submitting a build with a duplicate version number. It happens when a developer forgets to increment the developer-facing build version number before creating a new build. EAS Build can help manage developer-facing build versions automatically by incrementing these versions for you if you opt into using the [`remote` version source](#remote-version-source), which is the recommended behaviour. Optionally, you can choose to use a `local` app version source, which means you control versions manually in their respective config files. ## Remote version source > **warning** The `remote` version source is the recommended behavior from EAS CLI version `12.0.0`. If you are using an older version of the EAS CLI, `local` is the default. EAS servers can store and manage your app's developer-facing build version (`android.versionCode` and `ios.buildNumber`) remotely. To enable it, you need to set `cli.appVersionSource` to `remote` in **eas.json**. Then, under the `production` build profile, you can set the `autoIncrement` property to `true`. ```json eas.json { "cli": { /* @info The app version source is set to remote to store and manage the version of your app. */ "appVersionSource": "remote" /* @end */ }, "build": { "development": { /* @hide ... */ /* @end */ }, "preview": { /* @hide ... */ /* @end */ }, "production": { /* @info The autoIncrement property is set to true to automatically increment the android.versionCode and ios.buildNumber values. */ "autoIncrement": true /* @end */ } } /* @hide ... */ /* @end */ } ``` The remote version is initialized with the value from the local project. For example, if you have `android.versionCode` set to `1` in app config, when you create a new build using the remote version source, it will auto increment to `2`. However, if you do not have build versions set in your app config, the remote version will initialize with `1` when the first build is created. When the `remote` version property is enabled inside **eas.json**, the build version values stored in app config are ignored and not updated when the version is incremented remotely. The remote version source values are set on the native project when running a build, which is considered the source of truth for these values. You can safely remove these values from your app config. ### Syncing already defined versions to remote There are different scenarios where you already have versions set up for your project and want to increment from those versions when you create a new EAS Build. However, these existing versions might not be synced remotely with EAS. Some of these scenarios are: - You have already published your app in the app stores and want to continue using the same version numbers. - EAS CLI is not able to detect what version the app is on. - For any other reason, you have versions explicitly set, such as inside your app config. In these scenarios, you can sync the current version to EAS Build using the EAS CLI using the following steps: - In the terminal window, run the following command: - Select the platform (Android or iOS) when prompted. - When prompted **Do you want to set app version source to remote now?**, select **yes**. This will set the `cli.appVersionSource` to `remote` in **eas.json**. - When prompted **What version would you like to initialize it with?**, enter the last version number that you have set in the app stores. After these steps, the app versions will be synced to EAS Build remotely. You can now set `build.production.autoIncrement` to `true` in **eas.json**. When you create a new production build, the `versionCode` and `buildNumber` will be automatically incremented. ### Syncing versions from remote to local To build your project locally in Android Studio or Xcode using the same version stored remotely on EAS, update your local project with the remote versions using the following command: ### Limitations - `eas build:version:sync` command on Android does not support bare projects with multiple flavors. However, the rest of the remote versioning functionality should work with all projects. - `autoIncrement` does not support the `version` option. - It's not supported if you are using EAS Update and runtime policy set to `"runtimeVersion": { "policy": "nativeVersion" }`. For similar behavior, use the `"appVersion"` policy instead. ## Local version source > **warning** The `remote` version source as a recommended behavior has been introduced in `eas-cli` version `12.0.0`. If you are using an older version of the CLI, you **don't need to specify the version source explicitly to `local`**. You can configure your project so that the source of truth for project versions is the local project source code itself. To do this, set `cli.appVersionSource` to `local` in your **eas.json**. With this setup, EAS reads app version values and builds projects as they are. It doesn't write to the project. You can also enable auto incrementing versions locally by setting the `autoIncrement` option on a build profile. ```json eas.json { "cli": { /* @info The app version source is set to local for you to manage the version of your app manually. */ "appVersionSource": "local" /* @end */ }, "build": { "development": { /* @hide ... */ /* @end */ }, "preview": { /* @hide ... */ /* @end */ }, "production": { /* @info The autoIncrement property is set to true to automatically increment the android.versionCode and ios.buildNumber values. */ "autoIncrement": true /* @end */ } } /* @hide ... */ /* @end */ } ``` In the case of [existing React Native projects](/bare/overview/), the values in native code take precedence. The libraries `expo-constants` and `expo-updates` read values from the app config file. If you rely on version values from a manifest, you should keep them in sync with native code. Keeping these values in sync is especially important if you are using EAS Update with the runtime policy set to `"runtimeVersion": { "policy": "nativeVersion" }`, because mismatched versions may result in the delivery of updates to the wrong version of an application. We recommend using [`expo-application`](/versions/latest/sdk/application/#constants) to read the version instead of depending on values from app config. ### Limitations - With `autoIncrement`, you need to commit your changes on every build if you want the version change to persist. This can be difficult to coordinate when building on CI. - For existing React Native projects with Gradle configuration that supports multiple flavors, EAS CLI is not able to read or modify the version, so `autoIncrement` option is not supported, and versions will not be listed in the build details page on [expo.dev](https://expo.dev).

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jaksm/expo-docs-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server