Claude Code running in Termux on an Android phone, launching Anon Browser and dumping its UI through a Shizuku helper script

Three Claude Code skills from building an Android app entirely in Termux

—

by

in ,

Anon Browser is an Android app with a real Tor daemon embedded in it, and it was built entirely on-device from Termux. No laptop. I should be upfront that I didn’t write it by hand: I guided Claude Code through the whole project, describing what I wanted, testing each build on my phone, and sending it back when something didn’t work. Along the way the agent kept running into problems that were specific, repeatable, and not well documented anywhere. Every time it had to re-discover one of them, we lost time, so I had it write the fixes down as Claude Code skills. They now live in their own repo: android-termux-skills.

Claude Code running in Termux on an Android phone, launching Anon Browser and dumping its UI through a Shizuku helper script
Claude Code running in Termux on the phone, launching Anon Browser and dumping its UI through a Shizuku helper script.

1. android-termux-build

Building a real Gradle Android project from Termux or a proot-distro container works, but the friction is very specific. These are the things the agent tripped over, and that the skill now spells out:

  • chmod +x exits 0 on FUSE-backed shared storage and does nothing, so ./gradlew never works and everything gets run as sh gradlew.
  • AGP’s Maven-published aapt2 is built for glibc, and Termux is Bionic, so the fix is to override it with Termux’s own build.
  • A bare proot-distro login doesn’t bind the project path, and a command after -- skips your dotfiles, so scripts have to set their own PATH and JAVA_HOME.
  • pm install fails on a path under /sdcard because system_server can’t read through FUSE. The APK has to be copied to /data/local/tmp first, and then checking lastUpdateTime confirms the install actually landed.
  • Keeping the release keystore out of the repo, and pinning a dependency that ships a non-16KB-aligned native lib.

2. shizuku-termux-agents

An agent living in Termux can’t reach pm, am, dumpsys, uiautomator or input directly. Shizuku bridges that gap without root, but the stock rish script broke inside the agent’s sandboxed shell. After some trial and error it landed on calling app_process64 directly instead, which is what the skill documents. It also covers the real privilege level (uid=2000 shell, not root), driving UI through uiautomator and input, and the other direction: an app handing tasks to the agent through Termux’s RUN_COMMAND intent.

Anon Browser connected to Tor, with its Self-Modify panel showing a failed Claude build and proot warnings
Anon Browser’s Self-Modify panel hands a change request to Claude in Termux through RUN_COMMAND. This attempt didn’t go well.

3. android-tor-integration

This one is about embedding an actual tor binary in an app instead of delegating to Orbot. I knew what I wanted the app to do; the agent worked out most of how. The skill covers shipping the daemon as libtor.so and why it needs useLegacyPackaging, a minimal torrc, the control-port protocol (including the easy-to-miss 250 OK desync), routing WebView through the SOCKS port only after bootstrap completes so nothing leaks, running it from a foreground service, and wiring up obfs4 and webtunnel bridges. One detail I picked up along the way and liked: circuits to .onion addresses end at a Rendezvous point, not an Exit, so a circuit viewer has to handle both.

Using them

Drop the folders into ~/.claude/skills/, or into a project’s .claude/skills/, and Claude Code picks them up when your task matches. They’re plain markdown, so they’re also a decent reference even if you never run an agent. I’m sure there are Termux and Android gotchas we never hit, so if you find one, pull requests are welcome.