Building an APK locally with Expo gives you greater control over your development workflow, allowing you to generate a standalone Android package without depending on Expo’s cloud build services.
This approach is particularly valuable for developers who need faster iteration, offline capabilities, or want to customize their build process.
In this blog, we’ll walk you through the steps to build an APK locally using Expo, highlight the tools you'll need, and cover potential challenges you might face along the way.
Prerequisites
Before you begin, ensure you have the following installed:
- Node.js (Latest LTS version recommended)
- Expo CLI (npm install -g expo-cli)
- Android Studio (with Android SDK and emulator support)
- EAS CLI (npm install -g eas-cli)
Step 1: Initialise an Expo project
If you don’t already have an Expo project, create one with the following command:
npx create-expo-app myApp
cd myApp
Step 2: Configure Expo for bare workflow
By default, Expo manages builds in the cloud, but to generate an APK locally, we need to prebuild our project:
npx expo prebuild
This command converts your managed Expo project into a bare React Native project with the necessary Android and iOS folders.
Step 3: Open the project in Android studio
- Open Android Studio.
- Click Open and navigate to your project’s android directory.
- Let Android Studio sync the Gradle files.
- Ensure you have installed the required Android SDKs.
Step 4: Build the APK using Gradle
To build an APK, use the following command inside the android directory:
cd android
./gradlew assembleRelease
This process might take a few minutes. Once completed, your APK will be located in:
android/app/build/outputs/apk/release/app-release.apk
Step 5: Signing the APK (optional)
For distribution, you should sign your APK. Generate a keystore using:
keytool -genkeypair -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-key-alias
Move the generated keystore to android/app/ and update the android/app/build.gradle file to reference your signing details.


Step 6: Install and test the APK
Once the APK is built, install it on an Android device or emulator:
adb install android/app/build/outputs/apk/release/app-release.apk
You can now run and test your Expo-built Android application locally!
Alternative method: building APK locally with EAS build
EAS Build is available to anyone with an Expo account, regardless of whether you pay for EAS or use their Free plan. You can sign up at https://expo.dev/signup.
Expo also provides EAS Build (Expo Application Services), which allows you to build APKs locally without manually handling Gradle commands. Here’s how:
1. Install EAS CLI (if not installed already):
npm install -g eas-cli
2. Configure EAS for local builds:
eas build: configure
3. Run a local build:
Android: eas build --local --platform android
iOS: eas build --local --platform ios
Alternatively, you can use --platform all option to build for Android and iOS at the same time:
eas build --local --platform all
4. This command will build the APK on your local machine.
5. Find the generated APK:
- The built APK will be located inside the dist/ directory in your project.
Why use EAS build locally?
- Automates the build process without requiring manual Gradle commands.
- Works with both managed and bare workflows.
- Simplifies configuration and signing.
If you are already signed in to an Expo account using Expo CLI, you can skip the steps described in this section. If you are not, run the following command to log in:
eas login
You can check whether you are logged in by running
eas whoami
Configure the project
To configure an Android or an iOS project for EAS Build, run the following command:
eas build:configure
Expo APK local build: The challenges I faced & how I solved them
While building an APK locally with Expo, you might encounter various challenges. Here are some common issues and how to resolve them:
1. Gradle version issues
Problem: The Build fails due to incompatible Gradle versions.
Solution: Update your Gradle version in android/gradle/wrapper/gradle-wrapper.properties.
Find this line:
distributionUrl=https\://services.gradle.org/distributions/gradle-x.x.x-all.zip
Update it to the latest stable version. You can find the latest version here.
Example:
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip

Update Gradle Plugin (If Needed) android/build.gradle
find classpath 'com.android.tools.build:gradle:x.x.x'
Update it to the latest version found in Android Gradle Plugin release notes.
Ensure your Android SDK is current.
2. Java version mismatch
Problem: Gradle build fails due to incompatible Java versions.
Solution: Ensure you are using the correct Java version (usually Java 11 or Java 17) by setting it in your environment variables.
Open a terminal or command prompt and run: java -version
If the version is not Java 11 or Java 17, you need to update it.
Install the Correct Java Version
Windows: Download & install Java from Adoptium or Oracle.
Mac/Linux: Use Homebrew (Mac) or SDKMAN (Linux) to install:
brew install openjdk@17
macOS/Linux
Open the Terminal and edit your shell config:
nano ~/.zshrc # (For macOS with zsh)
nano ~/.bashrc # (For Linux or bash)
Add this
export JAVA_HOME=$(/usr/libexec/java_home -v 17)
export PATH=$JAVA_HOME/bin:$PATH
Apply changes:
source ~/.zshrc # or source ~/.bashrc
Verify the version:
java --version
Set Java Version in gradle.properties
Open:android/gradle.properties
Add: org.gradle.java.home=/path/to/java17
(Replace /path/to/java17 with your actual Java installation path.)
3. Dependency conflicts
Problem: Errors related to conflicting dependencies in package.json.
Solution: Run expo doctor to identify issues and resolve conflicts by upgrading/downgrading dependencies as needed.
4. Missing Android SDK or emulator issues
Problem: The build process cannot locate the required Android SDK.
Solution: Install and configure the Android SDK in Android Studio and set ANDROID_HOME and ANDROID_SDK_ROOT environment variables.
5. Build fails with Hermes
Problem: The app crashes or doesn't build due to the Hermes engine.
Solution: Try disabling Hermes by modifying android/app/build.gradle or ensure you are using a compatible Hermes version.
Check if Hermes is enabled
Open:
android/app/build.gradle
Find this block:
project.ext.react = [enableHermes: true // Change to false to disable Hermes]
If enableHermes: true, try switching it to false and rebuilding.
6. Slow build times
Problem: Gradle takes too long to compile the project.
Solution: Enable Gradle caching and daemon mode, and use a more powerful machine for faster builds.
Enable gradle daemon & caching
1. Open:
~/.gradle/gradle.properties
(If it doesn’t exist, create it.)
2. Add or modify these lines:
org.gradle.daemon=true # Keeps Gradle running in the background for faster builds
3. Enable build caching
org.gradle.caching=true # Enables build caching
4. Enable parallel execution
org.gradle.parallel=true # Enables parallel execution
5. Configures projects on demand
org.gradle.configureondemand=true # Configures projects on demand
6. Limits worker processes (adjust based on CPU)
org.gradle.workers.max=4 # Limits worker processes (adjust based on CPU)
Use a faster gradle distribution
1. Open
android/gradle/wrapper/gradle-wrapper.properties
2. Update to the latest Gradle version (check Gradle Releases):
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip
Allocate more RAM to gradle
1. Open
android/gradle.properties
2. Add
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -Dkotlin.daemon.jvm.options="-Xmx2g"(Increase -Xmx4g based on available RAM.)
Use incremental compilation
1. Open
android/build.gradle
2. Add this inside the android block:
android {...
compileOptions {
incremental true // Enables incremental Java compilation
}
}
Conclusion
Building APKs locally with Expo gives you complete control over your app’s build process, making it an excellent choice for offline development, thorough debugging, and distributing apps without depending on cloud-based services. This approach can be especially helpful when working in secure environments or when faster iteration cycles are needed.
However, it’s important to be prepared for some common hurdles along the way, such as Gradle version mismatches, dependency conflicts, or issues related to Android SDK configuration.
By identifying and addressing these challenges early, you can create a more reliable and streamlined build workflow.
With the right tools, attention to detail, and a clear understanding of the process, you can confidently build, test, and distribute your Expo-based Android applications entirely on your local machine.
Happy coding!