Setup Expo Build Environment on WSL2 (Without Android Studio nor Paying Expo Credits)

Published: (December 2, 2025 at 05:10 PM EST)
3 min read
Source: Dev.to

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!

Back to Blog

Related posts

Read more »