/004

termux-tools

“What if your phone were a real development machine, with agent and browser automation?”

Shipped Open source Android · Systems · Browser automation

// The question

A modern phone has more compute than the workstations most software was written on. It also has a shell, a package manager, and a browser. So why is “develop on your phone” still a punchline? Specifically: could you run a frontier coding agent, a fast JavaScript runtime, and full browser automation on a stock Android device, no root and no container tricks, and have it be good enough to build real things?

// The constraint

Android is Linux with the interesting parts filed off. Its bionic libc isn’t glibc, so binaries compiled for normal Linux don’t run. Its filesystem (f2fs) refuses hardlinks that package managers rely on. Manifest V3 extension service workers never start in sideloaded browser targets. And the tools you’d want (a bun-compiled agent binary, a Chromium-based browser) ship as opaque artifacts with telemetry welded on, not as things you’re meant to modify.

The standard workaround is proot or a chroot: emulate a whole Linux inside the phone. It works, and it’s slow, fragile, and defeats the point.

// The attack

Go underneath instead of around. Rather than emulating Linux, intercept the handful of syscalls that actually differ: a small C userland exec wrapper plus an LD_PRELOAD shim that catches openat, stat, execve, and link, spoofs /proc/stat, and quietly turns failed hardlinks into copies. That’s enough to run the real, unmodified Bun binary natively.

For the agent, patch the compiled binary’s embedded virtual filesystem in place with byte-preserving edits, equal-length overwrites so the offsets survive, instead of rebuilding it. For the browser, treat the vendor APK as source: unpack it, strip the tracking, stub the telemetry, and re-sign. Then bridge the browser to the agent over a WebSocket so screenshots, navigation, and JS-over-CDP show up as ordinary tools inside any agent session.

// The leverage

  • Termux. A real package ecosystem on Android that nobody asked permission to build. Everything here stands on it.
  • Interposition beats emulation. The official 100 MB Bun binary runs untouched. Roughly a thousand lines of C make it work, because the incompatibility is a handful of syscalls, not an operating system.
  • Binaries are editable. apktool, smali, and a hex editor turn a closed browser and a compiled agent into things you can reason about and change. The vendor’s build is a starting point, not a boundary.
  • The agent itself. An AI coding agent on the device compounds everything else: once it runs, it helps build the rest of the stack it’s running on.

// The build

One installer that wires up the whole stack on bionic Android: Bun via the userland exec shim (79 of 80 upstream tests passing); Claude Code (2.1.158 at time of writing) running natively through the byte-preserving patcher; an Edge Canary build with 64 manifest removals, 25 DEX method stubs, 15 native libraries stripped, and 35 telemetry endpoints redirected to 127.0.0.1, rebuilt reproducibly and re-signed, from the copy already on your phone if you like; and the CFC bridge, which registers as an MCP server so the agent can drive the browser. Plus the glue: x86_64 emulation via qemu for the stragglers, ADB wireless automation, a Ghostty source build.

termux.party: termux-tools landing page showing the installer, the CFC bridge, and the Edge debloat pipeline
FIG. 004-1 · termux.party. The Bun site at bun.termux.party was itself built on a phone, in Termux, because node couldn’t resolve its native binaries and bun-on-termux could.

// The failures

  • MV3 was a dead end. Service workers simply never start in a sideloaded CDP target on Edge Android; the bridge extension ships as an MV2 background page because nothing else works.
  • Patching the agent naively bricked it. The bun-compiled binary’s virtual filesystem is offset-sensitive; any edit that changed a byte count killed the whole thing. Byte-preserving overwrites were a constraint discovered the hard way.
  • Hardlinks. Package installs silently failed on f2fs until the shim learned to fall back to copies. A one-line cause that cost a disproportionate amount of time.
  • Not everything yields: one of Bun’s eighty tests still fails, and a few x86-only tools need the qemu path, which is slow.

// The result

A phone that is, unironically, a development machine: a current coding agent with browser automation, a native JS runtime, and a browser that has had its telemetry surgically removed. All on stock Android, no root, from a single bootstrap script. It’s in daily use, and the proof is circular in the best way: parts of this stack were built using the stack.

// The implication

The hardware in a pocket was never the limit. The limit was a stack of small incompatibilities and vendor decisions that nobody had bothered to unpick, because unpicking them wasn’t anyone’s job. Once an agent runs on the device, the cost of unpicking the rest drops again. Carry that forward and the “minimum viable dev environment” becomes whatever is already in your hand.

Notebook The landing page for the Bun shim was built on a phone with the Bun shim. That’s the whole experiment in one sentence.