# If you've downloaded the credentials from `eas credentials` command, see comments below for each value.
MYAPP_UPLOAD_STORE_FILE=my-upload-key.keystore     # Path to the "keystore" file
MYAPP_UPLOAD_KEY_ALIAS=my-key-alias                # Replace with value of the `keystore.keyAlias` field in the credentials.json file
MYAPP_UPLOAD_STORE_PASSWORD=*****                  # Replace with value of the `keystore.password` field in the credentials.json file
MYAPP_UPLOAD_KEY_PASSWORD=*****                    # Replace with value of the `keystore.keyPassword` field in the credentials.json file
```
> **warning** If you commit the **android** directory to a version control system like Git, don't commit the above information. Instead, create a **~/.gradle/gradle.properties** file on your computer and add the above variables to this file.
Step 3: 
### Add signing config to build.gradle
Open **android/app/build.gradle** file and add the following configuration:
<DiffBlock source="/static/diffs/android-release-build.diff" />
Step 4: 
### Generate release Android Application Bundle (aab)
Navigate inside the **android** directory and create a release build in **.aab** format by running Gradle's `bundleRelease` command:
```sh
$ cd android
$ ./gradlew app:bundleRelease
```
This command will generate app-release.aab inside the **android/app/build/outputs/bundle/release** directory.
Step 5: 
### Manual app submission to Google Play Console
Google Play Store requires manual app submission when submitting the **.aab** file for the first time.
## iOS
To create an iOS release build locally for Apple App Store, you need to use Xcode which handles the signing and submission process via App Store Connect.
### Prerequisites
- Paid Apple Developer membership
- [Xcode installed](/get-started/set-up-your-environment/?platform=ios&device=physical&mode=development-build&buildEnv=local#set-up-xcode-and-watchman) on your computer
- **ios** directory generated. If you are using [CNG](/workflow/continuous-native-generation/), then run `npx expo prebuild` to generate it.
Step 1: 
### Open iOS workspace in Xcode
Inside your Expo project directory, run the following command to open `your-project.xcworkspace` in Xcode:
```sh
$ xed ios
```
After opening the iOS project in Xcode:
1. From the sidebar on the left, select your app's workspace.
2. Go to **Signing & Capabilities** and select **All** or **Release**.
3. Under **Signing** > **Team**, ensure your Apple Developer team is selected. Xcode will generate an automatically managed Provisioning Profile and Signing Certificate.
Step 2: 
### Configure a release scheme
To configure your app's release scheme:
1. From the menu bar, open **Product** > **Scheme** > **Edit Scheme**.
2. Select **Run** from the sidebar, then set the **Build configuration** to **Release** using the dropdown.
Step 3: 
### Build app for release
To build your app for release, From the menu bar, open **Product** > **Build**. This step will build your app binary for release.
Step 4: 
### App submission using App Store Connect
Once the build is complete, you can distribute your app to TestFlight or submit it to the App Store using App Store Connect:
1. From the menu bar, open **Product** > **Archive**.
2. Under **Archives**, click **Distribute App** from the right sidebar.
3. Click **App Store Connect** and follow the prompts shown in the window. This step will create an app store record and upload your app to the App Store.
4. Now you can go to your App Store Connect account, select your app under Apps, and submit it for testing using TestFlight or prepare it for final release by following the steps in the App Store Connect dashboard.


## Use build cache providers

Accelerate local development by caching and reusing builds from a provider.

Build caching is a feature that speeds up `npx expo run:[android|ios]` by caching builds remotely, based on the project [fingerprint](/versions/latest/sdk/fingerprint/).
When you run `npx expo run:[android|ios]`, it checks if a build with a matching fingerprint exists, then downloads and launches it rather than compiling it again. Otherwise, the project is compiled as usual and then the resulting binary is uploaded to the remote cache for future runs.
## Using EAS as a build provider
To use the EAS Build provider plugin, start by installing the `eas-build-cache-provider` package as a developer dependency:
For macOS/Linux: 
```sh
$ npx expo install eas-build-cache-provider --dev
```
For Windows: 
```sh
$ npx expo install eas-build-cache-provider "--" --dev
```
Then, update your **app.json** to include the `buildCacheProvider` property and its provider:
```json app.json
{
  "expo": {
    "buildCacheProvider": "eas"
  }
}
```
You can roll your own cache provider by exporting a plugin that implements the following methods:
```ts
type BuildCacheProviderPlugin<T = any> = {
  /**
   * Try to fetch an existing build. Return its URL or null if missing.
   */
  resolveBuildCache(props: ResolveBuildCacheProps, options: T): Promise<string | null>;
  /**
   * Upload a new build binary. Return its URL or null on failure.
   */
  uploadBuildCache(props: UploadBuildCacheProps, options: T): Promise<string | null>;
  /**
   * (Optional) Customize the fingerprint hash algorithm.
   */
  calculateFingerprintHash?: (
    props: CalculateFingerprintHashProps,
    options: T
  ) => Promise<string | null>;
};
type ResolveBuildCacheProps = {
  projectRoot: string;
  platform: 'android' | 'ios';
  runOptions: RunOptions;
  fingerprintHash: string;
};
type UploadBuildCacheProps = {
  projectRoot: string;
  buildPath: string;
  runOptions: RunOptions;
  fingerprintHash: string;
  platform: 'android' | 'ios';
};
type CalculateFingerprintHashProps = {
  projectRoot: string;
  platform: 'android' | 'ios';
  runOptions: RunOptions;
};
```
A reference implementation using GitHub Releases to cache builds can be found in the [Build Cache Provider Example](https://github.com/expo/examples/tree/master/with-github-remote-build-cache-provider).
## Creating a custom build provider
Start by creating a **provider** directory for writing the provider plugin in TypeScript and add a **provider.plugin.js** file in the project root, which will be the plugin's entry point.
Step 1: 
### Create a `provider/tsconfig.json` file
```json provider/tsconfig.json
{
  "extends": "expo-module-scripts/tsconfig.plugin",
  "compilerOptions": {
    "outDir": "build",
    "rootDir": "src"
  },
  "include": ["./src"],
  "exclude": ["**/__mocks__/*", "**/__tests__/*"]
}
```
Step 2: 
### Create a `provider/src/index.ts` file for your plugin
```ts provider/src/index.ts
import { type BuildCacheProviderPlugin } from '@expo/config';
const plugin: BuildCacheProviderPlugin = {
  resolveBuildCache: async () => {
    console.log('Searching for remote builds...');
    return null;
  },
  uploadBuildCache: async () => {
    console.log('Uploading build to remote...');
    return null;
  },
};
export default plugin;
```
Step 3: 
### Create an `provider.plugin.js` file in the root directory
```js provider.plugin.js
// This file configures the entry file for your plugin.
module.exports = require('./provider/build');
```
Step 4: 
### Build your provider plugin
At the root of your project, run `npm run build provider` to start the TypeScript compiler in watch mode.
Step 5: 
### Configure your example project to use your plugin by adding the following line to the `example/app.json` file:
```json example/app.json
{
  "expo": {
    "buildCacheProvider": {
      "plugin": "./provider.plugin.js"
    }
  }
}
```
Step 6: 
### Test your provider
When you run the `npx expo run` command inside your **example** directory, you should see your plugin's console statements in the logs.
```sh
$ cd example
$ npx expo run:android
$ npx expo run:ios
```
That's it! You now have a remote build cache provider to speed up your builds.
### Passing custom options
To inject custom options to your plugin you can use the `options` field and it will be forwarded as the second parameter of your custom functions. To do so modify the `buildCacheProvider` field in **example/app.json** as shown below:
```json example/app.json
{
  "expo": {
    "buildCacheProvider": {
      "plugin": "./provider.plugin.js",
      "options": {
        "myCustomKey": "XXX-XXX-XXX"
      }
    }
  }
}
```


## Prebuilt Expo Modules for Android

Learn how prebuilt Expo Modules reduce Android build times by up to 25% on your machine.

When building React Native apps, longer build times can slow down your development workflow and reduce productivity. Each time you make changes to your code, you might need to wait for the build process to complete, which can add up to significant delays.
**Starting from SDK 53**, Expo introduces prebuilt Expo Modules for Android to address this pain point. Instead of compiling Expo Modules source code from scratch during each build, your project can now use pre-compiled versions of these modules. Ultimately, this results in faster build times.
## Benefits
- **Faster local development**: Up to 25% reduction in Android build times on local machines
- **Improved developer experience**: Less waiting time during development iterations
- **Automatic optimization**: Works out of the box with new projects for SDK 53 and later
## How prebuilt Expo Modules for Android work
During your project's Android build process, look for the `[ð¦]` emoji prefix next to package names in the build output. This indicates that those packages are using prebuilt versions rather than being compiled from source.
For example, after creating a project with SDK 53's default template, and running the `npx expo run:android` command, you will notice the `[ð¦ package-name` prefix next to packages that are precompiled:
## Configuration
**For SDK 53 and later, no configuration steps are required for projects** that are created with one of the available [Expo templates](/more/create-expo/#--template).
### Opting out of prebuilt Expo Modules
You can opt out of prebuilt modules. This might be required when you are modifying the module source code yourself. In this scenario, you can configure the Expo Autolinking configuration by adding `buildFromSource` to the **package.json** file:
```json package.json
{
  "name": "your-app-name",
  "expo": {
    "autolinking": {
      "android": {
        "buildFromSource": [
          ".*"
        ]
      }
    }
  }
}
```
### Selectively opt out
You can also opt out of specific modules while keeping others prebuilt by specifying individual package names instead of the wildcard `".*"`:
```json package.json
{
  "name": "your-app-name",
  "expo": {
    "autolinking": {
      "android": {
        "buildFromSource": [
          "expo-camera",
          "expo-web-browser",
          "expo-linking",
        ]
      }
    }
  }
}
```
## Considerations
- Existing projects can benefit from this feature when upgrading to SDK 53 and later
- Performance improvements may vary based on your hardware configuration
- Current improvements on EAS Builds are more modest but provide groundwork for future caching mechanisms