Termux on Android (Non-Root): Complete Setup & Optimization Guide
TL;DR: Turn any Android 7.0+ phone into a Linux lab without root. This guide covers the official install (F-Droid or GitHub — skip the restricted Play Store build), first-run configuration, essential packages, proot-distro containers, and the honest truth about memory and swap. You'll need Android 7.0+, roughly 5 GB free storage, and a willingness to read /proc/swaps before trusting anyone's "free RAM" trick.
Two hours into "optimizing" a fresh Termux install, I was still smug. I'd created a 2 GB swap file, mkswap had formatted it clean, swapon had… waited. Operation not permitted. I had just executed the exact steps half the tutorials on the internet tell you to run — and the kernel had told me to sit down.
That's the thing about Termux: it's a real Linux userspace, and a real Linux kernel says no to you when you have no root. The good news: almost everything that matters still works without it. This is the version of the guide I wish I'd read first — install, first-run config, containers, memory facts, and SSH — every claim checked against stock Android, August 2026.
Install Termux from Official Sources Only (Skip the Play Store)
The Play Store situation changed while most tutorials weren't looking. Termux got pulled from Google Play in 2021, then quietly returned in June 2024 — but as an unofficial, restricted fork. The core team's own announcement calls the Play Store release "functionally equivalent to v0.108", with ten releases of bug and security fixes reverted, reduced permissions, and no RUN_COMMAND intent. It's Android 11+ only, and the team still lists F-Droid and GitHub as the only official sources.
⚠ The Play Store build is a forked release source maintained outside the core team (github.com/termux-play-store). Features are missing, fixes are reverted, and it may be taken down if it keeps violating Play policy. Install it at your own risk — or just don't.
Option 1: F-Droid (Recommended)
F-Droid carries the actively maintained app and the whole plugin ecosystem, all signed and updated from one repo. As of this writing the latest stable is 0.118.3, with 0.119.0-beta.3 available if you like living on the edge.
# On your Android device, open F-Droid and search "Termux"
# Install all of these from the SAME source (F-Droid):
# - Termux (main app)
# - Termux:API (hardware access: camera, GPS, sensors, clipboard)
# - Termux:Boot (run scripts on device boot)
# - Termux:Widget (home-screen shortcuts)
Why F-Droid wins: automatic updates, every plugin in one repo, no Google Play Services dependency, and a signed build the Termux team controls.
Option 2: GitHub Releases (Direct APK)
Can't use F-Droid? Grab the current stable from the official repo. The naming pattern is termux-app_v<version>+github-debug_<arch>.apk — not the _apk-<arch> format floating around in older guides.
# Visit: https://github.com/termux/termux-app/releases
# Download: termux-app_v0.118.3+github-debug_arm64-v8a.apk
# (match the suffix to your architecture — see table below)
# Verify the hash before installing — the release ships a checksum file:
# grep arm64-v8a termux-app_v0.118.3+github-debug_sha256sums | sha256sum -c -
Architecture mapping:
| Device Architecture | APK Suffix |
|---|---|
| ARM64 (most modern phones) | arm64-v8a |
| ARM32 (older devices) | armeabi-v7a |
| x86_64 (emulators, Chromebooks) | x86_64 |
| x86 (old emulators) | x86 |
Enable Unknown Sources & Install
# Settings → Security → Install unknown apps → [Your browser / F-Droid] → Allow
# Open the downloaded APK → Install
Pro tip: on Android 13+ you'll hit a "Restricted settings" warning. That's normal — Termux needs unrestricted battery usage for background jobs (sshd, cron). Grant it: Settings → Apps → Termux → Battery → Unrestricted.
⚠ One source, all apps. Every Termux app shares the sharedUserId com.termux and must be signed with the same key. Never mix F-Droid and GitHub builds — plugins will silently refuse to talk to the main app and you'll end up uninstalling everything. Pick F-Droid or GitHub for the app and every plugin.
First Run: Updates, Storage & the Filesystem Layout
Launch Termux. You land in $HOME (/data/data/com.termux/files/home). Do these in order — they're cheap and they prevent 90% of the "why is nothing working" threads on r/termux.
1. Update the Package Index & Upgrade
pkg update && pkg upgrade -y
Expected output: tens to hundreds of packages upgraded. First run takes 2–5 minutes on decent hardware. If you see repository errors, run termux-change-repo and pick a mirror close to you.
2. Grant Storage Access
termux-setup-storage
Tap "Allow" on the system dialog. The script broadcasts an intent to the app, which then rebuilds the symlink tree in $HOME:
~/storage/shared→ shared storage~/storage/downloads→/sdcard/Download~/storage/dcim→/sdcard/DCIM~/storage/music,~/storage/pictures,~/storage/movies
Gotcha: on Android 11+ scoped storage, the symlinks are the only sane way in — raw /sdcard/... writes break in ways that are painful to debug. Revoked the permission later? The symlinks go dead. Re-grant it in Settings → Apps → Termux → Permissions, then re-run termux-setup-storage — it rebuilds the whole tree from scratch.
3. Know Your Filesystem
| Path | Points to | What lives there |
|---|---|---|
$PREFIX | /data/data/com.termux/files/usr | Installed packages — treat as read-only |
$HOME | /data/data/com.termux/files/home | Your scripts, configs, data |
$TMPDIR | /data/data/com.termux/files/usr/tmp | Temp files |
~/storage/shared | Android shared storage | Files visible to other apps |
Key insight: $PREFIX belongs to the package manager. Your stuff goes in $HOME. Writing into $PREFIX by hand gets silently clobbered on the next upgrade — I've lost a dotfile collection that way.
4. Shell Setup
# Default shell is bash
echo $SHELL
# Optional: zsh + oh-my-zsh
pkg install zsh git -y
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
chsh -s zsh
Pro tip: keep bash as the default for script compatibility and hop into zsh interactively with exec zsh when you want the pretty prompt. chsh ships with termux-tools, so this just works.
Essential Packages: Build Your Mobile Toolkit
One command, the whole foundation:
pkg install -y \
git curl wget \
vim nano \
htop tree \
zip unzip \
openssh \
python nodejs \
build-essential \
proot-distro \
termux-api
Package Breakdown
| Package | Purpose | When You'll Use It |
|---|---|---|
git | Version control | Cloning repos, CTF tools, dotfiles |
curl/wget | HTTP clients | Downloading scripts, API testing |
vim/nano | Editors | Config editing, quick scripts |
htop | Process monitor | Finding the memory hog before it finds you |
tree | Directory visualization | Navigating project structures |
zip/unzip | Archives | CTF challenges, file transfer |
openssh | SSH client/server | Remote access, Git over SSH |
python | Scripting | Exploit dev, tooling, data parsing |
nodejs | JavaScript runtime | Web tools, modern CLI apps |
build-essential | Toolchain metapackage | clang + make + pkg-config for compiling |
proot-distro | Linux distro containers | Full Ubuntu/Kali/Arch userspaces, no root |
termux-api | Android hardware bridges | WiFi info, clipboard, battery, sensors |
Note on termux-api: the package (currently v0.59.1) installs the CLI scripts, but the commands only talk to hardware if you also install the Termux:API app from the same source. Same rule as everything else: F-Droid app + F-Droid package, or GitHub + GitHub.
Verify the Install
git --version
python3 --version
node --version
ssh -V
proot-distro --help
termux-clipboard-get # needs the Termux:API app installed
Run Full Linux Distros with proot-distro (No Root)
proot-distro is at v5.6.0 (August 2026), and it changed shape: it's now an OCI-image tool — think docker pull without the daemon. Containers are assembled from Docker Hub images, and a bunch of old flag names are gone. The good news: it's simpler.
# Browse Docker Hub from the terminal
proot-distro search ubuntu
# Ubuntu (pin the LTS if you want stability)
proot-distro install ubuntu
# Kali — the OFFICIAL image name is kalilinux/kali-rolling
# (a bare `install kali` does not resolve on Docker Hub)
proot-distro install kalilinux/kali-rolling
# Arch — official image, rolling and minimal
proot-distro install archlinux
Truth bomb about Kali: the official image ships no tools by default. "Pentesting tools pre-installed" is a myth from the old rootfs-based builds. Inside Kali, run apt update && apt install -y kali-linux-headless (or just install the specific tool you need — nmap, metasploit-framework, whatever). Cleaner and faster than pulling the kitchen sink.
Enter a Distro
# Interactive shell (you're root inside by default)
proot-distro login ubuntu
# Explicit — the default anyway
proot-distro login ubuntu --user root
# One command, multi-step — wrap in bash -c so && runs INSIDE the distro
proot-distro login ubuntu -- bash -c "apt update && apt install -y nmap"
# Share Termux's tmp as /tmp inside the container
proot-distro login ubuntu --shared-tmp
# Bare-minimum proot: only /dev, /proc, /sys — for weak kernels or tight RAM
proot-distro login ubuntu --minimal
Rabbit hole I fell into: proot-distro login ubuntu -- apt update && apt install -y nmap runs apt install on the host after the login exits — a classic "why is this in my Termux home?" moment. The -- separator passes a command into the container's shell, so anything more than one command needs bash -c "...".
Persistent Aliases
# Add to ~/.bashrc (or ~/.zshrc)
alias ubuntu='proot-distro login ubuntu'
alias kali='proot-distro login kalilinux/kali-rolling'
alias ubuntu-root='proot-distro login ubuntu --user root'
Now ubuntu drops you into a real Ubuntu userspace with apt, gcc, and all the toys — no kernel modules, no root, no ROM surgery.
Memory on Non-Root Android: The ZRAM & Swap Reality Check
Here's where I ate my words — and where most Termux guides lie to you. On stock, non-rooted Android you cannot add swap space. Period.
mkswapandswapondo ship inside Termux'sutil-linuxpackage — but theswapon(2)syscall demandsCAP_SYS_ADMIN, and Android's SELinux policy denies it to theuntrusted_appdomain. You getOperation not permitted.- Writing to
/sys/block/zram0/*or runningmodprobe zram? Root. Full stop. - Android already runs ZRAM at the kernel level on most devices — it's configured by init scripts, not by you.
⚠ Swap on stock Android needs root. The "swap file without root" tutorials you'll find are either outdated, or they quietly assume a vendor ROM. Some devices (notably Xiaomi/HyperOS with "Memory Extension") do permit unprivileged swapon — but that's undocumented, kernel-specific behavior, and one widely-reported case left a persistent 6 GB ZRAM allocation the owner could not remove. Don't build your workflow on it.
What Actually Works Non-Root: Check, Then Shrink
# Look at what the kernel already set up (read-only, no root needed)
cat /proc/swaps
swapon --show
zramctl # zram devices, listed read-only
If ZRAM shows up here, it's already working — Android's memory manager (LMKD) will swap pages into it under pressure. Your job is to make the pressure smaller:
- Run a lighter distro:
proot-distro install alpineinstead of Ubuntu. - Log in with
--minimalto drop the heavy host bindings. - Close background Android apps — real RAM, zero magic.
- Watch
htopinside Termux and kill the leak instead of band-aiding it.
Root-Only Option: A Real Swap File
Rooted device? Then — and only then — swap is on the table. Run these from a root shell (Magisk's su or Termux's tsu), not plain Termux:
# From a ROOT shell (tsu or Magisk su) — fails on stock Android
dd if=/dev/zero of=/data/local/tmp/swapfile bs=1M count=2048
mkswap /data/local/tmp/swapfile
swapon /data/local/tmp/swapfile
# Verify
cat /proc/swaps
⚠ Rooted only. Skip this section on a stock phone. Even with root, a swap file on flash wears the eMMC and is slower than ZRAM — if your ROM already runs ZRAM, you're done; if it doesn't, buy a phone with more RAM instead of grinding your storage into virtual memory.
Keep Termux Alive: Battery Exemptions, Wake Locks & Boot Scripts
Android kills background apps. That's the #1 reason sshd "disappears" mid-session. Three layers of defense, in order:
1. Battery Exemptions (Android Settings)
# Settings → Apps → Termux → Battery → Unrestricted
# Settings → Apps → Termux:API → Battery → Unrestricted
# Settings → Apps → Termux:Boot → Battery → Unrestricted
2. Wake Lock (Terminal)
termux-wake-lock # hold a wakelock so the CPU stays alive in background
termux-wake-unlock # release it when you're done
3. Termux:Boot Script (Device Boot)
mkdir -p ~/.termux/boot
cat > ~/.termux/boot/start-sshd << 'EOF'
#!/data/data/com.termux/files/usr/bin/bash
# Grab a wake lock and bring up sshd at device boot
termux-wake-lock
sshd
EOF
chmod +x ~/.termux/boot/start-sshd
Cleaner alternative: runit services. pkg install termux-services -y, then sv-enable sshd — it supervises the daemon and restarts it if it dies, which a boot script won't.
SSH Daemon on Port 8022: Make Your Phone a Server
Termux's OpenSSH (currently 10.5p1) listens on port 8022 by default — port 22 is privileged, and you're not root. Key-only auth, bind it to your WiFi IP, done right.
Start the Daemon
# Generate a keypair (first time only)
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N ""
# Start sshd
sshd
# Confirm it's listening
ss -tln | grep 8022 # or: netstat -tlnp | grep 8022 (install net-tools)
Connect from Another Device
# On your laptop — replace username and IP
ssh -p 8022 u0_a123@192.168.1.50
# Find your username (run on the phone)
whoami # e.g. u0_a123
# Find the phone's IP — robust: field order in `ip route get` varies
ip route get 1.1.1.1 | awk '{for (i=1; i<=NF; i++) if ($i == "src") print $(i+1)}'
# Or via Termux:API (JSON output — needs jq installed)
termux-wifi-connectioninfo | jq -r .ip
Why not awk '{print $7}'? Some iproute2 builds inject proto dhcp or other fields before src, shifting the column. Scanning for the src token is build-proof — I learned that the hard way on a vendor ROM.
Harden sshd_config
The config lives at $PREFIX/etc/ssh/sshd_config — not ~/.ssh/, which is a mistake a lot of guides make. Drop in a hardened version with your real username baked in:
# Back up the stock config first — package upgrades will leave your file
# alone, but you still want a way back
cp "$PREFIX/etc/ssh/sshd_config" "$PREFIX/etc/ssh/sshd_config.bak"
# Bake in your username — unquoted heredoc expands it
ALLOWED_USER="$(whoami)"
cat > "$PREFIX/etc/ssh/sshd_config" <<EOF
Port 8022
AddressFamily inet
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no
KbdInteractiveAuthentication no
UsePAM no
Compression yes
ClientAliveInterval 30
ClientAliveCountMax 4
SyslogFacility AUTH
LogLevel INFO
AllowUsers ${ALLOWED_USER}
EOF
pkill sshd 2>/dev/null; sshd
Two corrections vs. the older guides: ChallengeResponseAuthentication was deprecated in OpenSSH 8.4 and replaced by KbdInteractiveAuthentication — use the new name. And a single-quoted heredoc ('EOF') would have written the literal string $(whoami) into your config and locked you out. The unquoted form above expands it for real.
Copy Your Public Key
# From your laptop — ssh-copy-id ships inside Termux's openssh package
ssh-copy-id -p 8022 -i ~/.ssh/id_ed25519.pub u0_a123@192.168.1.50
# Manual equivalent:
# scp -P 8022 ~/.ssh/id_ed25519.pub u0_a123@192.168.1.50:~/.ssh/authorized_keys
⚠ Running sshd means your LAN can reach your phone — and your phone has no firewall you control. Key-only auth is the floor, not the ceiling: never port-forward 8022 to the internet (use WireGuard for remote access), and consider binding ListenAddress to your WiFi IP instead of listening on every interface.
Bonus: Kill the Animations (ADB, No Root)
Cosmetic, but the phone feels faster and it costs nothing:
# From your PC with USB debugging enabled — no root required
adb shell settings put global window_animation_scale 0.5
adb shell settings put global transition_animation_scale 0.5
adb shell settings put global animator_duration_scale 0.5
⚠ Needs USB debugging (adb) or root. Purely cosmetic — skip it if you can't be bothered.
Gotchas & Rabbit Holes
"Permission denied" on Storage Writes
Cause: Android 11+ scoped storage. Fix: use ~/storage/shared/Download, never hardcoded /sdcard/.... Revoked the permission? Re-run termux-setup-storage.
proot-distro Fails to Start a Session
Cause: kernel too old for the image's syscalls, or a session that refuses to come up under heavy bindings. Fix: drop to the bare session — proot-distro login ubuntu --minimal — or install a featherweight image: proot-distro install alpine. The old ubuntu-minimal / --variant minimal incantations from older guides no longer exist in v5.x.
SSH Connection Refused / Timeout
pgrep sshd— is it even running?ss -tln | grep 8022— listening?- Battery optimization killed it — check "Unrestricted" again.
- Router/AP client isolation blocking LAN traffic — phone can't reach your PC either.
- Debug with
sshd -din the foreground and read the config errors.
Python / Node Native Modules Fail to Compile
# Toolchain first — build-essential covers clang, make, pkg-config
pkg install -y build-essential
# numpy/pandas: the BLAS backends make a real difference
pkg install -y libopenblas liblapack
# node native modules: headers ship with nodejs itself
pkg install -y nodejs python3 make clang
Termux Killed in Background on Android 12+
Android 12+ caps "phantom" processes at 32 per app and kills anything burning excessive CPU. Symptoms: [Process completed (signal 9)] out of nowhere. Battery exemption + termux-wake-lock helps; for heavy jobs, run them inside a distro or in chunks.
Termux Crashes on Startup
# A bad .bashrc can brick your interactive session — rename and restart
mv ~/.bashrc ~/.bashrc.bak
# Prefer a clean reset over a full reinstall
termux-reset # restores default configs, keeps packages and $HOME
Out of Memory / Killed Processes
Non-root fixes only — no swap tricks here:
- Close background Android apps (real RAM).
- Lighter distro:
proot-distro install alpine, then--minimal. htopand find the leak instead of fighting the symptom.
Takeaways
- One source, all apps — F-Droid or GitHub, never both. Every Termux app shares a signing key and
sharedUserId; mixing sources quietly breaks plugins and forces a wipe. - The kernel's rules still apply — non-root Termux cannot create swap or reconfigure ZRAM; Android manages it. Check
/proc/swaps, then spend your effort on footprint (alpine,--minimal) instead of fake RAM. - proot-distro is an OCI tool now —
install kalilinux/kali-rolling(notkali), Kali ships zero tools by default, pinubuntu:24.04, and use--shared-tmp/--minimalto control the session. - Battery exemption + wake lock + Termux:Boot = a server that stays up — Android will kill sshd within minutes without all three. And harden it: key-only, port 8022, config at
$PREFIX/etc/ssh/sshd_config, never forward to the internet.
Anchor Insight
Termux isn't a "Linux simulator" — it's a real Linux userspace on the kernel your phone already runs. Non-root doesn't mean "can't do much"; it means the kernel's rules apply to you exactly as they do to any unprivileged user. Learn where root is genuinely required (swap, ZRAM,
/syswrites) and where it isn't (packages, containers, SSH, storage) — and a $200 phone becomes a serious lab.
Related Articles (Internal Linking)
- Kali Linux in Termux: proot-distro vs. Nethunter vs. chroot — Choose the right Kali setup for your threat model
- Android Pentesting Without Root: Network Recon & MITM — Turn your Termux-hardened phone into a field assessment toolkit
- SSH Hardening for Exposed Services — Apply the same SSH config principles to your VPS fleet
Last verified: August 14, 2026 | Termux v0.118.3 stable (0.119.0-beta on F-Droid) | proot-distro v5.6.0 | Android 7.0–16 tested
