Running Claude Code on Android via proot-distro
Published on 7/21/2026
Anthropic doesn’t support Android. But it still runs, through an Ubuntu layer inside proot.
The problem
Claude Code is a linux-arm64 binary dynamically linked against glibc. Termux runs on Android’s bionic libc. Installing directly via npm gives you an error:
Unsupported platform: android arm64
The workaround: build an Ubuntu rootfs inside Termux using proot-distro, which has real glibc, then install Claude Code inside that.
Requirements
- An aarch64 device, Android 8+ - check with
uname -m - Termux installed from F-Droid (the Play Store build has stopped receiving updates)
- ~2GB of free space
Installation
In Termux:
pkg update -y && pkg upgrade -y
pkg install proot-distro -y
proot-distro install ubuntu
proot-distro login ubuntu
In Ubuntu:
apt update && apt install -y curl git
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt install -y nodejs
npm install -g @anthropic-ai/claude-code
claude
The first time you run claude it will open a browser login flow. Use your existing Claude account - no API key needed.
A convenient alias
Add this to Termux’s ~/.bashrc, not Ubuntu’s:
alias claude='proot-distro login ubuntu -- bash -lc "claude"'
From then on you just type claude.
Notifications when Claude needs attention
Claude Code has a Notification hook (fires when it needs permission/input) and a Stop hook (fires when it’s done). Wire termux-notification into those, and tapping the notification brings you back to Termux.
Install (in Termux, not Ubuntu):
pkg install termux-api -y
Also install the Termux:API app from F-Droid - the termux-api package is just a script that calls into that app via intent; without the app, the commands won’t run.
Tapping the notification doesn’t automatically reopen Termux - this is the part that eats the most time. The am start called from the notification’s action runs inside Termux:API’s background service, and Android 10+ blocks activity starts from the background by default (the Background Activity Launch restriction). Fix it by granting Termux the overlay permission:
Settings → Apps → Termux → Advanced → Display over other apps → Allow
Without this permission, am start runs “successfully” (exit 0) but doesn’t bring the app to the foreground - easy to mistake for a command syntax error.
Use the full path for the command, since termux-notification’s action runs in its own shell with no $PATH:
termux-notification --title "Claude Code" --content "..." \
--action "/data/data/com.termux/files/usr/bin/am start --user 0 -n com.termux/com.termux.app.TermuxActivity"
--user 0 is required - without it, Termux’s am (its own reimplementation, not Android’s real am) throws a SecurityException due to missing INTERACT_ACROSS_USERS_FULL.
Wire this into ~/.claude/settings.json inside Ubuntu:
{
"hooks": {
"Notification": [
{ "hooks": [ { "type": "command",
"command": "jq -r '.message // .title // \"Claude needs your attention\"' | { read -r msg; termux-notification --title \"Claude Code\" --content \"$msg\" --action \"/data/data/com.termux/files/usr/bin/am start --user 0 -n com.termux/com.termux.app.TermuxActivity\" --id 42; } 2>/dev/null || true" } ] }
],
"Stop": [
{ "hooks": [ { "type": "command",
"command": "termux-notification --title \"Claude Code\" --content \"Claude stopped — check the session\" --action \"/data/data/com.termux/files/usr/bin/am start --user 0 -n com.termux/com.termux.app.TermuxActivity\" --id 42 2>/dev/null || true" } ] }
]
}
}
After editing settings.json, open /hooks once (or start a new claude session) so it reloads - editing the file while a session is running doesn’t apply automatically.
Running multiple Termux tabs at once means the notification won’t automatically pick the right tab. am start only brings the Termux app to the front, showing whichever tab is currently “current” - Termux doesn’t expose any intent for an outside app to select a specific existing session by name/ID (checked the RUN_COMMAND wiki and source; the session-action part only applies when creating a new session). To get control over this: merge your projects into a single tmux server (one named window per project), keep exactly one Termux tab attached to it, and have the notification’s action run tmux select-window -t <name> before am start. This part hasn’t been thoroughly verified yet.
Limitations
This is a workaround, not an officially supported solution.