Programming

How to Set Up React Native CLI on Linux Without Android Studio

How to Set Up React Native CLI on Linux Without Android Studio

React Native Android development does not strictly require Android Studio. Android Studio is the easiest official way because it installs the Android SDK, platform tools, emulator, build tools, and environment variables for you.

zlaam

zlaam

April 27, 2026·7 views1

React Native Android development does not strictly require Android Studio. Android Studio is the easiest official way because it installs the Android SDK, platform tools, emulator, build tools, and environment variables for you. But if you prefer a clean Linux setup, you can install everything manually using only command-line tools.

This guide shows two approaches:

  1. One-shot setup script
  2. Manual step-by-step setup

This is useful for Kubuntu, Ubuntu, Pop!_OS, Zorin OS, Linux Mint, or any Ubuntu-based Linux distribution.


Requirements

We will install:

Node.js 22+
Java JDK 17
Android SDK command-line tools
Android platform-tools
Android SDK Platform 35
Android SDK Build-Tools 36.0.0
ADB
React Native CLI

Android Studio is not required.


Part 1: One-Shot Setup Script

Create a file:

nano setup-react-native.sh

Paste this full script:

#!/bin/sh

set -e

ANDROID_SDK_VERSION="14742923"
ANDROID_CMDLINE_ZIP="commandlinetools-linux-${ANDROID_SDK_VERSION}_latest.zip"
ANDROID_CMDLINE_URL="https://dl.google.com/android/repository/${ANDROID_CMDLINE_ZIP}"

ANDROID_HOME_DIR="$HOME/Android/Sdk"
CMDLINE_TOOLS_DIR="$ANDROID_HOME_DIR/cmdline-tools"
CMDLINE_LATEST_DIR="$CMDLINE_TOOLS_DIR/latest"
CMDLINE_DUPLICATE_DIR="$CMDLINE_TOOLS_DIR/latest-2"

REQUIRED_NODE_MAJOR=22
JAVA_HOME_PATH="/usr/lib/jvm/java-17-openjdk-amd64"

RC_FILES="$HOME/.zshrc $HOME/.bashrc"

echo "=========================================="
echo " React Native Android setup without Studio"
echo "=========================================="
echo

append_block_if_missing() {
  file="$1"
  marker="$2"
  content="$3"

  touch "$file"

  if grep -q "$marker" "$file"; then
    echo "Already configured in $file: $marker"
  else
    echo "Adding config to $file"
    {
      echo
      echo "# $marker"
      echo "$content"
      echo "# END $marker"
    } >> "$file"
  fi
}

install_apt_packages() {
  echo
  echo "Checking apt packages..."

  sudo apt update

  sudo apt install -y \
    curl \
    wget \
    unzip \
    zip \
    git \
    openjdk-17-jdk \
    build-essential \
    libssl-dev \
    adb

  echo "Apt packages are installed."
}

check_node() {
  echo
  echo "Checking Node.js..."

  if command -v node >/dev/null 2>&1; then
    NODE_VERSION_RAW="$(node -v)"
    NODE_MAJOR="$(echo "$NODE_VERSION_RAW" | sed 's/^v//' | cut -d. -f1)"

    if [ "$NODE_MAJOR" -ge "$REQUIRED_NODE_MAJOR" ]; then
      echo "Node.js is OK: $NODE_VERSION_RAW"
    else
      echo "Node.js exists but version is too old: $NODE_VERSION_RAW"
      echo "Required: Node.js $REQUIRED_NODE_MAJOR+"
      echo "Android setup will continue, but React Native may fail until Node is upgraded."
    fi
  else
    echo "Node.js is not installed."
    echo "Required: Node.js $REQUIRED_NODE_MAJOR+"
    echo "Android setup will continue, but React Native may fail until Node is installed."
  fi
}

configure_java_home() {
  echo
  echo "Configuring JAVA_HOME..."

  if [ ! -d "$JAVA_HOME_PATH" ]; then
    echo "Warning: expected Java path does not exist:"
    echo "$JAVA_HOME_PATH"
    echo "Current Java:"
    java -version || true
    return 0
  fi

  JAVA_BLOCK="export JAVA_HOME=$JAVA_HOME_PATH"

  for rc in $RC_FILES; do
    append_block_if_missing "$rc" "JAVA 17 CONFIG - ADDED BY RN SETUP SCRIPT" "$JAVA_BLOCK"
  done

  export JAVA_HOME="$JAVA_HOME_PATH"

  echo "JAVA_HOME set to: $JAVA_HOME"
}

cleanup_duplicate_cmdline_tools() {
  echo
  echo "Checking duplicate command-line tools folders..."

  if [ -d "$CMDLINE_DUPLICATE_DIR" ]; then
    echo "Removing duplicate folder:"
    echo "$CMDLINE_DUPLICATE_DIR"
    rm -rf "$CMDLINE_DUPLICATE_DIR"
  else
    echo "No duplicate latest-2 folder found."
  fi
}

cmdline_tools_exist() {
  [ -x "$CMDLINE_LATEST_DIR/bin/sdkmanager" ] && [ -x "$CMDLINE_LATEST_DIR/bin/avdmanager" ]
}

install_cmdline_tools_manually() {
  echo
  echo "Installing Android command-line tools manually..."

  mkdir -p "$CMDLINE_TOOLS_DIR"
  mkdir -p "$HOME/Downloads"

  cd "$HOME/Downloads"

  if [ -f "$ANDROID_CMDLINE_ZIP" ]; then
    echo "Command-line tools zip already exists:"
    echo "$HOME/Downloads/$ANDROID_CMDLINE_ZIP"
  else
    echo "Downloading Android command-line tools..."
    wget "$ANDROID_CMDLINE_URL" -O "$ANDROID_CMDLINE_ZIP"
  fi

  TEMP_EXTRACT_DIR="$HOME/Downloads/android-cmdline-tools-extract"

  rm -rf "$TEMP_EXTRACT_DIR"
  mkdir -p "$TEMP_EXTRACT_DIR"

  echo "Extracting command-line tools..."
  unzip -q "$ANDROID_CMDLINE_ZIP" -d "$TEMP_EXTRACT_DIR"

  rm -rf "$CMDLINE_LATEST_DIR"
  mkdir -p "$CMDLINE_TOOLS_DIR"

  if [ -d "$TEMP_EXTRACT_DIR/cmdline-tools" ]; then
    mv "$TEMP_EXTRACT_DIR/cmdline-tools" "$CMDLINE_LATEST_DIR"
  else
    echo "Error: extracted cmdline-tools folder not found."
    exit 1
  fi

  rm -rf "$TEMP_EXTRACT_DIR"

  echo "Android command-line tools installed at:"
  echo "$CMDLINE_LATEST_DIR"
}

ensure_android_cmdline_tools() {
  echo
  echo "Checking Android command-line tools..."

  cleanup_duplicate_cmdline_tools

  if cmdline_tools_exist; then
    echo "Android command-line tools already installed:"
    echo "$CMDLINE_LATEST_DIR"
    return 0
  fi

  echo "Android command-line tools not found."
  install_cmdline_tools_manually

  if ! cmdline_tools_exist; then
    echo "Error: command-line tools installation failed."
    exit 1
  fi
}

configure_android_env() {
  echo
  echo "Configuring Android environment variables..."

  ANDROID_BLOCK='export ANDROID_HOME=$HOME/Android/Sdk
export ANDROID_SDK_ROOT=$ANDROID_HOME

export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$ANDROID_HOME/emulator'

  for rc in $RC_FILES; do
    append_block_if_missing "$rc" "ANDROID SDK CONFIG - ADDED BY RN SETUP SCRIPT" "$ANDROID_BLOCK"
  done

  export ANDROID_HOME="$ANDROID_HOME_DIR"
  export ANDROID_SDK_ROOT="$ANDROID_HOME"
  export PATH="$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator"

  echo "ANDROID_HOME=$ANDROID_HOME"
}

verify_android_tools() {
  echo
  echo "Verifying Android tools..."

  if [ ! -x "$CMDLINE_LATEST_DIR/bin/sdkmanager" ]; then
    echo "sdkmanager not found at:"
    echo "$CMDLINE_LATEST_DIR/bin/sdkmanager"
    exit 1
  fi

  if [ ! -x "$CMDLINE_LATEST_DIR/bin/avdmanager" ]; then
    echo "avdmanager not found at:"
    echo "$CMDLINE_LATEST_DIR/bin/avdmanager"
    exit 1
  fi

  echo "sdkmanager:"
  command -v sdkmanager || true

  echo "avdmanager:"
  command -v avdmanager || true

  echo "adb:"
  command -v adb || true

  echo
  echo "Files inside cmdline tools bin:"
  ls "$CMDLINE_LATEST_DIR/bin"
}

accept_android_licenses() {
  echo
  echo "Accepting Android SDK licenses..."
  yes | sdkmanager --licenses || true
}

is_sdk_package_installed() {
  package="$1"
  sdkmanager --list_installed 2>/dev/null | awk '{print $1}' | grep -qx "$package"
}

install_sdk_package_if_missing() {
  package="$1"

  if is_sdk_package_installed "$package"; then
    echo "Already installed: $package"
  else
    echo "Installing: $package"
    sdkmanager "$package"
  fi
}

install_android_sdk_packages() {
  echo
  echo "Checking Android SDK packages..."

  install_sdk_package_if_missing "platform-tools"
  install_sdk_package_if_missing "platforms;android-35"
  install_sdk_package_if_missing "build-tools;36.0.0"

  if cmdline_tools_exist; then
    echo "Command-line tools already exist at correct location:"
    echo "$CMDLINE_LATEST_DIR"
  else
    echo "Command-line tools missing. Installing manually..."
    install_cmdline_tools_manually
  fi

  cleanup_duplicate_cmdline_tools

  echo "Android SDK packages are ready."
}

final_check() {
  echo
  echo "=========================================="
  echo " Final verification"
  echo "=========================================="
  echo

  echo "Node:"
  if command -v node >/dev/null 2>&1; then
    node -v
  else
    echo "Node not installed"
  fi

  echo
  echo "Java:"
  java -version || true

  echo
  echo "JAVA_HOME:"
  echo "${JAVA_HOME:-not set}"

  echo
  echo "ANDROID_HOME:"
  echo "${ANDROID_HOME:-not set}"

  echo
  echo "sdkmanager:"
  command -v sdkmanager || true

  echo
  echo "sdkmanager version:"
  sdkmanager --version || true

  echo
  echo "adb:"
  command -v adb || true

  echo
  echo "adb version:"
  adb version || true

  echo
  echo "Command-line tools folders:"
  ls -la "$CMDLINE_TOOLS_DIR" || true

  echo
  echo "Installed required Android SDK packages:"
  sdkmanager --list_installed | grep -E "platform-tools|platforms;android-35|build-tools;36.0.0|cmdline-tools" || true

  echo
  echo "Done."
  echo
  echo "Restart your terminal or run:"
  echo "source ~/.zshrc"
}

main() {
  install_apt_packages
  check_node
  configure_java_home
  ensure_android_cmdline_tools
  configure_android_env
  verify_android_tools
  accept_android_licenses
  install_android_sdk_packages
  final_check
}

main "$@"

Save and exit.

Make it executable:

chmod +x setup-react-native.sh

Run it:

./setup-react-native.sh

After it finishes, restart the terminal or run:

source ~/.zshrc

For Bash users:

source ~/.bashrc

What This Script Does

The script installs required Linux packages:

sudo apt install -y \
  curl \
  wget \
  unzip \
  zip \
  git \
  openjdk-17-jdk \
  build-essential \
  libssl-dev \
  adb

It checks your Node.js version:

node -v

If Node.js is version 22+, it leaves it alone. If Node.js is missing or older, it warns you but continues Android setup.

It installs Android command-line tools here:

~/Android/Sdk/cmdline-tools/latest

It adds permanent environment variables to both:

~/.zshrc
~/.bashrc

These variables are added:

export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64

export ANDROID_HOME=$HOME/Android/Sdk
export ANDROID_SDK_ROOT=$ANDROID_HOME

export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$ANDROID_HOME/emulator

It installs Android SDK packages:

platform-tools
platforms;android-35
build-tools;36.0.0

It also avoids the common duplicate folder problem:

~/Android/Sdk/cmdline-tools/latest-2

That duplicate usually happens when command-line tools are manually unzipped and then installed again using:

sdkmanager "cmdline-tools;latest"

This script checks whether command-line tools already exist before installing them.


Verify the Installation

Run:

node -v
java -version
echo $JAVA_HOME
echo $ANDROID_HOME
which sdkmanager
sdkmanager --version
which adb
adb version

Expected result should look like this:

node v22+ or v24+
openjdk version "17.x"
JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
ANDROID_HOME=/home/your-user/Android/Sdk
sdkmanager=/home/your-user/Android/Sdk/cmdline-tools/latest/bin/sdkmanager
adb=/usr/bin/adb

Check installed SDK packages:

sdkmanager --list_installed | grep -E "platform-tools|platforms;android-35|build-tools;36.0.0"

Expected:

build-tools;36.0.0
platform-tools
platforms;android-35

Check command-line tools folder:

ls -la ~/Android/Sdk/cmdline-tools

Expected:

latest

There should not be:

latest-2

Part 2: Manual Setup

This section explains how to do the same setup manually.


Step 1: Install Linux Dependencies

Run:

sudo apt update

Then install required packages:

sudo apt install -y \
  curl \
  wget \
  unzip \
  zip \
  git \
  openjdk-17-jdk \
  build-essential \
  libssl-dev \
  adb

Check Java:

java -version

Expected:

openjdk version "17.x"

Step 2: Set JAVA_HOME

For Ubuntu-based systems, OpenJDK 17 is usually installed here:

/usr/lib/jvm/java-17-openjdk-amd64

Add this to your shell config.

For Zsh:

nano ~/.zshrc

For Bash:

nano ~/.bashrc

Add:

export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64

Reload:

source ~/.zshrc

or:

source ~/.bashrc

Check:

echo $JAVA_HOME

Expected:

/usr/lib/jvm/java-17-openjdk-amd64

Step 3: Check Node.js

React Native requires a modern Node.js version. Use Node.js 22+.

Check:

node -v

Good:

v22.x.x
v24.x.x

If Node.js is not installed, install it using your preferred Node version manager.

Example with nvm:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash

Reload shell:

source ~/.zshrc

Install Node:

nvm install 22
nvm use 22
nvm alias default 22

Check:

node -v

Step 4: Download Android Command-Line Tools

Create SDK folder:

mkdir -p ~/Android/Sdk/cmdline-tools

Go to Downloads:

cd ~/Downloads

Download Android command-line tools:

wget https://dl.google.com/android/repository/commandlinetools-linux-14742923_latest.zip -O commandlinetools-linux-14742923_latest.zip

Extract:

unzip commandlinetools-linux-14742923_latest.zip -d ~/Android/Sdk/cmdline-tools

Move extracted folder to latest:

mv ~/Android/Sdk/cmdline-tools/cmdline-tools ~/Android/Sdk/cmdline-tools/latest

Verify:

ls ~/Android/Sdk/cmdline-tools/latest/bin

You should see:

sdkmanager
avdmanager

Step 5: Set Android Environment Variables

For Zsh:

nano ~/.zshrc

For Bash:

nano ~/.bashrc

Add:

export ANDROID_HOME=$HOME/Android/Sdk
export ANDROID_SDK_ROOT=$ANDROID_HOME

export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$ANDROID_HOME/emulator

Reload:

source ~/.zshrc

or:

source ~/.bashrc

Check:

echo $ANDROID_HOME
which sdkmanager
which adb

Expected:

/home/your-user/Android/Sdk
/home/your-user/Android/Sdk/cmdline-tools/latest/bin/sdkmanager
/usr/bin/adb

adb may also appear from:

/home/your-user/Android/Sdk/platform-tools/adb

Both are okay.


Step 6: Accept Android SDK Licenses

Run:

sdkmanager --licenses

Accept all licenses by typing:

y

To auto-accept:

yes | sdkmanager --licenses

Step 7: Install Required Android SDK Packages

Run:

sdkmanager \
  "platform-tools" \
  "platforms;android-35" \
  "build-tools;36.0.0"

Do not run this if you already manually installed command-line tools:

sdkmanager "cmdline-tools;latest"

That can create this duplicate folder:

~/Android/Sdk/cmdline-tools/latest-2

If it already exists, remove it:

rm -rf ~/Android/Sdk/cmdline-tools/latest-2

Verify installed packages:

sdkmanager --list_installed | grep -E "platform-tools|platforms;android-35|build-tools;36.0.0"

Expected:

build-tools;36.0.0
platform-tools
platforms;android-35

Part 3: Create a React Native Project

Use the React Native Community CLI.

Do not install old global react-native-cli.

Run:

npx @react-native-community/cli@latest init MyApp

Enter project:

cd MyApp

Start Metro:

npm start

In another terminal, run Android build:

npm run android

or:

npx react-native run-android

Part 4: Use a Real Android Device

You do not need an emulator if you have a physical Android phone.

On your phone:

Settings → About phone → tap Build number 7 times
Settings → Developer options → enable USB debugging

Connect the phone using USB.

Run:

adb devices

You may see:

unauthorized

Unlock your phone and allow USB debugging.

Run again:

adb devices

Expected:

List of devices attached
DEVICE_ID    device

Now run:

npm run android

Part 5: Optional Emulator Setup Without Android Studio

Install emulator packages:

sdkmanager \
  "emulator" \
  "system-images;android-35;google_apis;x86_64"

Create an Android Virtual Device:

avdmanager create avd \
  -n Pixel_7_API_35 \
  -k "system-images;android-35;google_apis;x86_64" \
  -d pixel_7

Start emulator:

emulator -avd Pixel_7_API_35

If the emulator command is not found, check:

echo $PATH

Make sure this exists in your shell config:

export PATH=$PATH:$ANDROID_HOME/emulator

Part 6: Common Problems and Fixes

Problem: sdkmanager: command not found

Check:

ls ~/Android/Sdk/cmdline-tools/latest/bin

If sdkmanager exists, your PATH is wrong.

Add this to ~/.zshrc or ~/.bashrc:

export ANDROID_HOME=$HOME/Android/Sdk
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin

Reload:

source ~/.zshrc

Problem: ANDROID_HOME is empty

Check:

echo $ANDROID_HOME

If empty, add:

export ANDROID_HOME=$HOME/Android/Sdk
export ANDROID_SDK_ROOT=$ANDROID_HOME

Reload shell:

source ~/.zshrc

Problem: latest-2 folder appears

This happens when you manually install command-line tools and then run:

sdkmanager "cmdline-tools;latest"

Fix:

rm -rf ~/Android/Sdk/cmdline-tools/latest-2

Check:

ls -la ~/Android/Sdk/cmdline-tools

Expected:

latest

Problem: Gradle cannot find SDK

Inside your React Native project, create or edit:

nano android/local.properties

Add:

sdk.dir=/home/your-user/Android/Sdk

Example:

sdk.dir=/home/siraj/Android/Sdk

Then run again:

npm run android

Problem: Wrong Java version

React Native Android builds usually work best with Java 17.

Check:

java -version

If you have multiple Java versions and want to manage them like Node.js with nvm, use SDKMAN.

Install SDKMAN:

curl -s "https://get.sdkman.io" | bash

Load it:

source "$HOME/.sdkman/bin/sdkman-init.sh"

List Java versions:

sdk list java

Install Java 17:

sdk install java 17.0.14-tem

Use it:

sdk use java 17.0.14-tem

Set as default:

sdk default java 17.0.14-tem

Check:

java -version
echo $JAVA_HOME

Final Verification

At the end, these commands should work:

node -v
java -version
echo $JAVA_HOME
echo $ANDROID_HOME
which sdkmanager
sdkmanager --version
which adb
adb version
sdkmanager --list_installed | grep -E "platform-tools|platforms;android-35|build-tools;36.0.0"

Expected setup:

Node.js 22+
Java 17
ANDROID_HOME=/home/your-user/Android/Sdk
sdkmanager available
adb available
platform-tools installed
platforms;android-35 installed
build-tools;36.0.0 installed

Now your Linux machine is ready for React Native Android development without Android Studio.

zlaam

zlaam

Author

Comments (0)

You need to be logged in to post comments

No comments yet. Be the first to share your thoughts!