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
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:
- One-shot setup script
- 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
Author
Comments (0)
You need to be logged in to post comments