Setup Expo Build Environment on WSL2 (Without Android Studio nor Paying Expo Credits)
Source: Dev.to
Why Even Build Locally?
1️⃣ Expo Cloud Builds cost money
Expo gives a small free quota. After that, you pay per build — which is fine for production, but not for rapid iteration or testing.
Local builds = unlimited free builds.
2️⃣ Android Studio is huge and unnecessary
A full Android Studio install includes IDE, emulators, GUI tools, and extras you don’t need for CI‑style builds.
You only need the command‑line SDK, build‑tools, platform‑tools, and NDK.
My setup installs only what is required, trimming the install from ~30 GB → ~3 GB.
Full Setup Guide (WSL2 Ubuntu 24.04)
Works for Expo, React Native CLI, EAS Build.
Matches Expo’s cloud build environment.
No Android Studio required.
1) Base Dependencies
sudo apt update
sudo apt install -y build-essential git unzip zip curl wget ca-certificates openjdk-17-jdk
2) Node 20.19.4 (matches Expo CI)
Expo’s cloud logs showed Node 20.19.4, so we install that with NVM:
export NVM_DIR="$HOME/.nvm"
if [ ! -d "$NVM_DIR" ]; then
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
fi
source "$NVM_DIR/nvm.sh"
nvm install 20.19.4
nvm alias default 20.19.4
Optional package managers:
npm i -g yarn@1.22.22 pnpm@10.14.0 bun@1.2.20
3) Android SDK + Build‑tools + NDK r27b (minimal install)
No Android Studio. Only the components required for building APK/AAB.
Download command‑line tools
export ANDROID_HOME="$HOME/Android/Sdk"
mkdir -p "$ANDROID_HOME"
cd /tmp
wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip -O cmdtools.zip
mkdir -p "$ANDROID_HOME/cmdline-tools"
unzip -q cmdtools.zip -d "$ANDROID_HOME/cmdline-tools"
mv "$ANDROID_HOME/cmdline-tools/cmdline-tools" "$ANDROID_HOME/cmdline-tools/tools"
Add to PATH
export PATH="$ANDROID_HOME/cmdline-tools/tools/bin:$ANDROID_HOME/platform-tools:$PATH"
Accept licenses
yes | sdkmanager --licenses
Install core packages
sdkmanager "platform-tools" \
"platforms;android-35" \
"build-tools;35.0.0" \
"build-tools;29.0.3" \
"ndk;27.1.12297006" \
"extras;google;m2repository" \
"extras;android;m2repository"
Set NDK env
export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/27.1.12297006"
4) Java + Gradle config
Expo uses Java 17 and specific Gradle JVM args:
export JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64"
export GRADLE_OPTS='-Dorg.gradle.jvmargs="-XX:MaxMetaspaceSize=1g -Xmx4g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8" -Dorg.gradle.parallel=true -Dorg.gradle.daemon=false'
5) Expo / EAS CLI + Tools
npm i -g expo-cli eas-cli
Optional but useful
Maestro
curl -Ls "https://get.maestro.mobile.dev" | bash
Bundletool
sudo mkdir -p /opt/bundletool
sudo wget -q https://github.com/google/bundletool/releases/download/1.17.2/bundletool-all-1.17.2.jar -O /opt/bundletool/bundletool.jar
echo 'alias bundletool="java -jar /opt/bundletool/bundletool.jar"' >> ~/.bashrc
6) Add Environment Variables Permanently
Append the following to ~/.bashrc:
# Android SDK
export ANDROID_HOME="$HOME/Android/Sdk"
export ANDROID_SDK_ROOT="$ANDROID_HOME"
export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/27.1.12297006"
export PATH="$HOME/.nvm/versions/node/v20.19.4/bin:/opt/bundletool:$ANDROID_HOME/build-tools/29.0.3:$ANDROID_HOME/build-tools/35.0.0:$ANDROID_NDK_HOME:$ANDROID_HOME/cmdline-tools/tools/bin:$ANDROID_HOME/platform-tools:$PATH"
# Java
export JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64"
# Expo Token
export EXPO_TOKEN=""
# Gradle
export GRADLE_OPTS='-Dorg.gradle.jvmargs="-XX:MaxMetaspaceSize=1g -Xmx4g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8" -Dorg.gradle.parallel=true -Dorg.gradle.daemon=false'
# CI‑like behavior
export CI=1
Apply the changes:
source ~/.bashrc
7) Verify Everything
node -v
npm -v
java -version
sdkmanager --list | head -n 50
bundletool --version
maestro --version
8) Do a Local EAS Build
Inside your Expo project:
npx eas build --local --platform android --profile production
Your build now runs without consuming Expo credits, and behaves exactly like their cloud runner.
Final Thoughts
This approach gives you:
- Zero‑cost unlimited builds
- A lightweight Android SDK install (no Studio needed)
- A reproducible environment across machines
- Perfect alignment with Expo CI logs
I built this by literally checking Expo’s cloud logs line‑by‑line, copying the exact versions, and replicating their environment on my local machine.
If you want, I can also generate:
- ✅ a one‑click install script for all of this
- ✅ a Docker version of the environment
- ✅ the macOS or Windows‑native variant
Just let me know!