Jervi
Back to all articles
expoeasreact nativewsl2ubuntu

Set Up an Expo Build Local Environment on WSL2

Set up a full Expo and Android build environment on WSL2 Ubuntu 24.04. Install Android SDK, NDK, Java 17, Node 20, EAS CLI, and configure all environment variables.

Here you go โ€” a clean, structured, publish-ready MDX article based on everything you wrote. I formatted it like a real technical guide (clear sections, code blocks, notes, warnings, tables, etc.).


๐Ÿ› ๏ธ Full Guide: Setting Up a Complete Expo / Android Build Environment on WSL2 (Ubuntu 24.04)

If you want to perform EAS local builds, Android native builds, or Maestro / bundletool automation inside WSL2, this guide gives you a fully reproducible setup identical to production CI workers.

This article covers:

  • Base Linux dependencies
  • Node 20.19.4 + npm 10.9.3
  • Yarn / pnpm / Bun
  • Java 17
  • Android SDK + Build-tools + NDK r27b
  • Expo / EAS CLI
  • Environment variables
  • Build verification

โœ… 0) System Overview (Target Configuration)

| Component | Version | | --------------- | ------------------------------------ | | OS | Ubuntu 24.04 (inside WSL2) | | Node.js | 20.19.4 | | npm | 10.9.3 | | Java | OpenJDK 17 | | Build-tools | 35.0.0 (plus 29.0.3 for compat) | | NDK | 27.1.12297006 (NDK r27b) | | Extras | Yarn, pnpm, Bun, Maestro, bundletool |

Environment variables configured:

JAVA_HOME
ANDROID_HOME
ANDROID_SDK_ROOT
ANDROID_NDK_HOME
EXPO_TOKEN
GRADLE_OPTS
PATH

๐Ÿš€ 1) Install Essential Packages

bash
sudo apt update
sudo apt install -y \
  build-essential git unzip zip curl wget ca-certificates \
  openjdk-17-jdk

โšก 2) Install Node 20.19.4 (CI-Compatible)

Install NVM

bash
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"

Install Node & npm

bash
nvm install 20.19.4
nvm alias default 20.19.4

node -v   # v20.19.4
npm -v    # 10.9.3

Extra package managers

bash
npm i -g yarn@1.22.22 pnpm@10.14.0 bun@1.2.20

๐Ÿ“ฑ 3) Install Android SDK + Build Plugins + NDK

Create SDK directory

bash
export ANDROID_HOME="$HOME/Android/Sdk"
mkdir -p "$ANDROID_HOME"

Install latest Android command-line tools

bash
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"

Update PATH temporarily

bash
export PATH="$ANDROID_HOME/cmdline-tools/tools/bin:$ANDROID_HOME/platform-tools:$PATH"

Accept all licenses

bash
yes | sdkmanager --licenses

Install required components

bash
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 path

bash
export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/27.1.12297006"

โ˜• 4) Java & Gradle Configuration

bash
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) Install Expo & EAS Tools

bash
npm i -g eas-cli expo-cli

Optional Tools

Maestro

bash
curl -Ls "https://get.maestro.mobile.dev" | bash

Bundletool

bash
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 'export PATH="/opt/bundletool:$PATH"' >> ~/.bashrc
echo 'alias bundletool="java -jar /opt/bundletool/bundletool.jar"' >> ~/.bashrc

๐Ÿ”ง 6) Persistent Environment Variables (~/.bashrc)

Append this to ~/.bashrc

bash
# 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"
bash
# Expo (replace with your actual token)
export EXPO_TOKEN="<your-expo-token>"

# Gradle settings
export GRADLE_OPTS='-Dorg.gradle.jvmargs="-XX:MaxMetaspaceSize=1g -Xmx4g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8" -Dorg.gradle.parallel=true -Dorg.gradle.daemon=false'

# Optional CI-like mode
export CI=1

Apply changes:

bash
source ~/.bashrc

and since we are using WSL2, we need to save also in ~/.profile

bash
nano ~/.profile

add in the bottom the following

bash
if [ -f "$HOME/.bashrc" ]; then
    source "$HOME/.bashrc"
fi

๐Ÿงช 7) Validate Everything

bash
node -v
npm -v
java -version

sdkmanager --list | head -n 50

echo $ANDROID_HOME
echo $ANDROID_NDK_HOME

bundletool --version
maestro --version

Sanity check folders:

bash
ls "$ANDROID_HOME"
ls "$ANDROID_NDK_HOME"

๐Ÿš€ 8) Test a Local EAS Build

Inside an Expo project:

bash
npx eas build --local --platform android --profile production

If everything is correct, the build will start without any Android or Java errors.


If an error for expo auth happened

then we should use auth through cli not with token

bash
unset EXPO_TOKEN
npx eas login

๐ŸŽ‰ Conclusion

You now have a 100% complete Expo Android build environment inside WSL2 Ubuntu 24.04, fully compatible with:

  • EAS local builds
  • React Native CLI builds
  • Gradle tasks
  • Maestro automation
  • Bundletool / APK / AAB manipulation
  • NDK-based native modules

This matches the same versions used by many CI runners, so your local builds will behave exactly the same.

If you want, I can also prepare:

โœ… A script to install ALL of this automatically โœ… A version for macOS โœ… A version for native Windows (no WSL) โœ… A Docker image for reproducible Android builds

Just tell me!