Run Claude Code natively on Termux/Android (aarch64).
Anthropic ships Claude Code only as bun-compiled glibc ELF binaries — there
is no android-arm64 build — so npm i -g @anthropic-ai/claude-code is broken on
Termux (claude-code#50270).
This package installs a small compiled launcher that downloads the official
linux-arm64 build from Anthropic, patches its ELF interpreter to Termux's
glibc loader so the kernel can exec it directly, and routes Claude's
embedded-tool re-execs (grep/find/rg) back through the launcher.
This project ships only its own shell scripts. The Claude Code binary is downloaded directly from Anthropic at install/first-run and patched locally on your device for interoperability — it is not redistributed by this project. Your use of Claude Code is governed by Anthropic's Commercial Terms of Service; this project only automates the download and the local patch.
This is the author's engineering reasoning, not legal advice.
curl -fsSL https://raw.githubusercontent.com/gtbuchanan/claude-code-termux/main/install.sh | bash
claudeinstall.sh enables the glibc package repo (the glibc-repo package), then
downloads the latest release .deb and installs it with apt, which pulls
glibc-runner, patchelf-glibc, jq, and python3 automatically. No manual
dependency install is needed. The package's postinstall then downloads and
patches the Claude Code binary, so claude works immediately.
glibc-runner and patchelf-glibc are not in Termux's default repos — they
live in termux-pacman/glibc-packages,
exposed to apt by the glibc-repo package. The installer enables it for you;
it cannot be a package Depends, because apt resolves dependencies before a
newly-added repo would be visible.
The package tracks the latest Claude Code release by default. To pin a
specific version, edit $PREFIX/etc/claude-code-termux.conf:
CLAUDE_CODE_VERSION=2.1.153then run claude-code-termux-update. The CLAUDE_CODE_VERSION environment
variable overrides the config file for one-off installs.
The binary is ~240 MB. To avoid re-downloading it on reinstalls or version
rollbacks — handy on slow or metered mobile connections — point
CLAUDE_CODE_CACHE_DIR (in $PREFIX/etc/claude-code-termux.conf, or the
environment) at a directory to cache it in:
CLAUDE_CODE_CACHE_DIR=$PREFIX/var/cache/claude-code-termuxThe cache holds the verified, pre-patch bytes; the ELF patch is still re-applied on every install, and a corrupt or stale entry is detected by its SHA-256 and re-downloaded. Leave it empty (the default) to disable caching.
aptinstalls the compiled launcher (claude), the bootstrap + patch helpers, and a config file, pulling the runtime dependencies.- The package's postinstall downloads the
linux-arm64binary from Anthropic, verifies its SHA-256, points its ELF interpreter at Termux's glibc loader (patchelf), and blanks the subprocessCLAUDE_CODE_EXECPATHassignment (patch-execpath.py) so embedded-tool re-execs route back through the launcher. - The compiled launcher execs the patched binary, preserving
argv[0]so Claude'sgrep/find/rgdispatch works. It overwritesLD_PRELOADwith two small shims: this evicts termux-exec'slibc.so(which the glibc binary's loader can't load) and preloads aunameshim that reports a< 5.11kernel so the bundled Bun skips anepoll_pwait2path that otherwise segfaults at startup on newer Android kernels (bun#32489), plus aresolvshim that points Bun's bundled c-ares resolver at$PREFIX/etc/resolv.conf(Android has no/etc/resolv.conf) so WebFetch, the claude.ai MCP connector, and OTEL export resolve DNS instead of hanging. It also setsTMPDIR/CLAUDE_CODE_TMPDIRto the Termux prefix (only when unset) since Termux has no writable/tmp. - The postinstall also symlinks the launcher onto Anthropic's native-install
path (
~/.local/bin/claude) so Claude's health check passes when it detectsinstallMethod: native. The symlink targets the launcher (not the patched binary), so the env setup still applies, andautoUpdates: falsekeeps the native self-updater from replacing it with a stock glibc build. A user-managed regular file at that path is left untouched.
Update later with claude-code-termux-update. It re-downloads and re-patches
only when the resolved version (latest, or your pin) differs from what's
installed, so it's safe to run unattended on a schedule — e.g. a daily
termux-job-scheduler job or a cron entry. Pass --force to re-apply the
current version (e.g. to repair a corrupted binary).
On install the package merges two keys Claude needs on Termux (skip with
CLAUDE_CODE_SKIP_SETTINGS=1, e.g. when a dotfile manager owns the file):
env.LD_PRELOAD→libtermux-exec-ld-preload.so. Re-arms termux-exec for subprocesses so#!/usr/bin/env …shebangs (pnpm, npx, …) resolve.autoUpdates→false. The in-session updater would otherwise overwrite the ELF-patched binary with a stock glibc one that won't exec.
If you set a custom statusLine.command, invoke it via bash explicitly (e.g.
bash ~/.claude/statusline) so the kernel never resolves a /usr/bin/env
shebang — there is no termux-exec preload inside the glibc claude process.
- MCP browser bridge. Claude hardcodes the MCP browser-bridge socket under
/tmpwith no env override, so that one feature can't write on Termux (where/tmpis unwritable). General temp use is fine — the launcher pointsTMPDIR/CLAUDE_CODE_TMPDIRat the Termux prefix, which covers Claude'sos.tmpdir()resolver and its sandbox subprocess. See anthropics/claude-code#15637.
The claude being run is an unpatched stock glibc binary: its ELF
interpreter points at /lib/ld-linux-aarch64.so.1, which doesn't exist on
Termux, so the kernel refuses to exec it. This package patches the interpreter
to Termux's glibc loader; the error means an unpatched binary is being resolved
instead.
It comes from Anthropic's native installer having run
(npm i -g @anthropic-ai/claude-code or claude install): that writes a stock
binary under ~/.local/share/claude/versions/ and repoints ~/.local/bin/claude
at it, shadowing this package's launcher.
Fix it with:
claude-code-termux-updateThe native installer leaves ~/.local/bin/claude as a symlink into
~/.local/share/claude/versions/, so this re-applies the ELF patch and
reconciles that path back onto the launcher in one step.
The stale stock binary it leaves under ~/.local/share/claude/versions/ is then
unreferenced and safe to remove.
On some Android setups the kernel won't launch the glibc binary Anthropic ships,
even after this package patches its ELF interpreter — the install detects this
and stops. First make sure Termux and termux-exec are fully up to date (older
termux-exec can't route execs the way newer Android requires) and retry. If it
still fails, the patch-and-exec approach this package relies on can't run here;
use an older, JavaScript-based Claude Code instead:
npm install -g @anthropic-ai/claude-code@2.1.112Drive the install from a dotfile manager and own settings.json yourself by
skipping the package's merge (CLAUDE_CODE_SKIP_SETTINGS=1) so your dotfiles
become the single source for the
keys it would otherwise add.
For a worked example, the author's dotfiles install the package with chezmoi, pinning both versions for Renovate and re-applying on a bump. The Android: claude-code-termux Package doc walks through it, backed by the version pins and install script.
pkg uninstall claude-code-termuxThis removes the launcher, the downloaded binary, and the native-path symlink
(~/.local/bin/claude, only if it still points at the launcher).
~/.claude/settings.json is left untouched.
- Termux on Android, aarch64
- Network access — the installer enables the
glibc-repoapt source and fetches Claude Code from Anthropic.glibc-runner(the glibc loader),patchelf-glibc,jq, andpython3are then installed automatically as package dependencies.
See CONTRIBUTING.md for the dev environment (mise), the dev tasks, and how the package is built and tested.
The scripts in this repository are MIT-licensed — see LICENSE. This covers only this project's code, not Claude Code (see Legal).