How to run Bun-based programs (Claude Code, opencode, Bun itself) on Termux/Android, using only what Termux already ships.
This is a guide, not a tool. There is no installer to run and nothing to patch. The whole trick is two Termux packages and a two-line wrapper.
Unofficial. Not affiliated with Anthropic, the opencode project, or Bun. This repo ships no binaries; every download below comes from the upstream project.
Claude Code and opencode both publish linux-arm64 binaries, but not an Android one. Each is a Bun runtime with the program compiled into it, and each is linked against glibc and asks for its loader at the fixed path /lib/ld-linux-aarch64.so.1. Android has no such path, and Termux runs on Bionic, so running the file directly fails (typically No such file or directory, even though the file exists). Anthropic's npm installer also reports the platform as android, which it has no build for (claude-code#50270).
Termux maintains a glibc repository, including glibc-runner, whose grun command starts a glibc binary with the right loader. Wrap each binary in a launcher that calls grun. No patchelf, no proot, no musl runtime.
pkg update
pkg install glibc-repo
pkg install glibc-runnerPick what you need. Each goes in its own folder under ~/.local/share/.
Claude Code (downloaded from Anthropic's own release endpoint, with a checksum from its manifest):
pkg install curl jq
BASE=https://downloads.claude.ai/claude-code-releases
V=$(curl -fsSL $BASE/latest)
mkdir -p ~/.local/share/claude
curl -fL -o ~/.local/share/claude/claude $BASE/$V/linux-arm64/claude
chmod +x ~/.local/share/claude/claude
# compare these two lines; they must match
curl -fsSL $BASE/$V/manifest.json | jq -r '.platforms["linux-arm64"].checksum'
sha256sum ~/.local/share/claude/claudeopencode:
mkdir -p ~/.local/share/opencode
curl -fL https://github.com/sst/opencode/releases/latest/download/opencode-linux-arm64.tar.gz \
| tar -xz -C ~/.local/share/opencodeUse the plain linux-arm64 build, not -musl.
Bun itself (to run JavaScript or TypeScript from source):
mkdir -p ~/.local/share/bun && cd ~/.local/share/bun
curl -fLO https://github.com/oven-sh/bun/releases/latest/download/bun-linux-aarch64.zip
unzip -o bun-linux-aarch64.zip # gives bun-linux-aarch64/bunA wrapper is a one-line script that hands the binary to grun:
mkdir -p ~/.local/bin
printf '#!/data/data/com.termux/files/usr/bin/sh\nexec grun "$HOME/.local/share/claude/claude" "$@"\n' > ~/.local/bin/claude
printf '#!/data/data/com.termux/files/usr/bin/sh\nexec grun "$HOME/.local/share/opencode/opencode" "$@"\n' > ~/.local/bin/opencode
printf '#!/data/data/com.termux/files/usr/bin/sh\nexec grun "$HOME/.local/share/bun/bun-linux-aarch64/bun" "$@"\n' > ~/.local/bin/bun
chmod +x ~/.local/bin/*
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrcCreate only the wrappers for what you downloaded, then open a new session (or source ~/.bashrc).
claude --version # 2.1.296 (Claude Code) when this was written
opencode --version # 1.19.0
bun --version # 1.4.3
claude auth status # runs; reports not logged in on a fresh installTo update, repeat step 2 for that program. The wrapper does not change.
One device, so treat this as evidence, not a guarantee.
| Device | Samsung Galaxy S10e (SM-G970W), Android 12 |
| Kernel | 4.14.190, aarch64 |
| glibc-runner | 2.0-3 |
| Claude Code | 2.1.296: --version and auth status run |
| opencode | 1.19.0: --version and models run (models list fetched over the network) |
| Bun | 1.4.3: fetch, file I/O, bun install of an npm package, require of it, and child_process spawn all worked |
Without grun |
./bun: not found, the original failure |
Not tested: an authenticated Claude Code or opencode session, tools run from inside them (git, ripgrep, shell), long sessions, other devices or Android versions, and Android 13+ kernels.
grunputs glibc's tools first onPATH. Programs started from a wrapped binary (bash, for example) resolve tousr/glibc/bin/..., not the normal Termux ones. Whether this matters for Claude Code's Bash tool orrgis untested here. See docs/pitfalls.md.- Minimal Termux lacks
gitandrg. Both CLIs use them. Runpkg install git ripgrep. ls /exited with status 2 from a spawned process under Bun. Not investigated.- Self-update. Claude Code can replace its own binary. A plain overwrite keeps the wrapper working, since the path does not change, but I have not watched one happen.
- docs/how-it-works.md: what is inside these binaries and why
grunis enough. - docs/pitfalls.md: failure modes, with what was seen here and what is carried over unverified.
- docs/carried-over/: reference notes from the two earlier repos (Claude Code hooks, Termux:API survey).
This replaces two earlier repos, both now archived. They worked by patching the binary's interpreter with patchelf (Claude Code) or by running it under an Alpine musl loader (opencode), and the Claude one grew a large set of helper scripts. Testing showed grun alone is enough.
CC BY 4.0. Programs you download keep their own licenses.