Skip to content

feat: Support Android (Termux)#12735

Open
gtbuchanan wants to merge 1 commit into
vercel:mainfrom
gtbuchanan:feat/android
Open

feat: Support Android (Termux)#12735
gtbuchanan wants to merge 1 commit into
vercel:mainfrom
gtbuchanan:feat/android

Conversation

@gtbuchanan
Copy link
Copy Markdown

Description

Termux on Android devices ships a Linux-compatible userspace and can run the existing linux-arm64 native binary unchanged. This change ships the Linux binaries on Android.

Note: I wasn't sure how receptive to this change you would be since the issue was previously rejected in 2023, so I chose the approach that resulted in fewer updates rather than creating a separate Android package (see j178/prek#1979 and j178/prek#1982 for reference). Let me know what you think

Resolves: #5616

Testing Instructions

I'm not sure how to test the npm resolution bit effectively without actually publishing the package. That's what the unit test is intended to cover. The launcher update can be verified in Termux by:

  1. Pack turbo in this branch
  2. Install via pnpm install -g path/to/turbo.tgz --force
  3. Run unset TURBO_BINARY_PATH (if set)
  4. Run turbo --version (this should print the version rather than Turborepo does not presently support your platform)

@gtbuchanan gtbuchanan requested a review from a team as a code owner May 6, 2026 17:24
@gtbuchanan gtbuchanan requested review from tknickman and removed request for a team May 6, 2026 17:24
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 6, 2026

@gtbuchanan is attempting to deploy a commit to the Vercel Team on Vercel.

A member of the Team first needs to authorize it.

Termux on Android devices ships a Linux-compatible userspace and
can run the existing `linux-64` and `linux-arm64` native binaries
unchanged.
@anthonyshew
Copy link
Copy Markdown
Contributor

Interesting. Do you have examples of other tools that have needed to make a similar change?

@gtbuchanan
Copy link
Copy Markdown
Author

If by "similar change" you mean deploying the same Linux package on both Linux and Android, then I do not have examples other than prek's first attempt (j178/prek#1979). It didn't work for prek because of the dependency on particular libc metadata, so they ended up creating a separate package that deployed the same binary instead.

It looks like oxc compiles a separate binary (as do other Rust packages), which is probably the more standard approach. I was just going for lower maintenance cost.

Turbo building against aarch64-unknown-linux-musl with -Clink-self-contained=yes appears to be what allows this approach to work. The x86_64-unknown-linux-musl build does not explicitly set it, but Rust appears to default to statically linked musl (which works on Android Bionic). I didn't separate Android arm64 from x64 because it would have increased complexity.

@anthonyshew
Copy link
Copy Markdown
Contributor

I'm meaning libraries having to specifically carve out Android into their support matrix. Are there PRs/code pointers/Issues popping up elsewhere on GitHub now that people are doing more development in Termux and Termux-like environments?

@gtbuchanan
Copy link
Copy Markdown
Author

gtbuchanan commented May 11, 2026

To avoid dumping a huge list of data points on you, I limited the search to Rust libraries currently shipped via npm. I also included a list of recent requests for a few other popular tools (not necessarily Rust).

Rust-via-npm projects that ship Android binaries today

Shared-os-array pattern

Project Implementation
sentry-cli All four @sentry/cli-linux-* packages have os: ["linux", "freebsd", "android"] (getsentry/sentry-cli#2524)

Separate-android-package pattern

Project Android package(s)
lightningcss lightningcss-android-arm64 (parcel-bundler/lightningcss#932)
unrs-resolver @unrs/resolver-binding-android-arm64 (unrs/unrs-resolver#154)
@parcel/watcher @parcel/watcher-android-arm64 (parcel-bundler/watcher#140)
@napi-rs/canvas @napi-rs/canvas-android-arm64 (Brooooooklyn/canvas#612)
oxc aarch64-linux-android napi target (oxc-project/oxc#11769)
@resvg/resvg-js @resvg/resvg-js-android-arm64 (thx/resvg-js#53)
prek @j178/prek-android-arm64 (j178/prek#1977 mine → j178/prek#1979j178/prek#1982)

Recent open requests

Tools without Android support whose issue trackers show ongoing demand.

Tool Latest Reference
bun 2026-05-09 oven-sh/bun#8685
codex 2026-04-17 openai/codex#17787
copilot-cli 2026-04-06 github/copilot-cli#1257
claude-code 2026-03-27 anthropics/claude-code#50270 (regression from v2.1.113 native install)
fnm 2026-03-13 Schniz/fnm#1486
dprint 2025-03-29 dprint/dprint#972

Already supported by other channels

Tool How Reference
node Termux package nodejs/node#58975
deno Termux package (Android-specific patches) denoland/deno#19759
esbuild Termux package (Go source build) evanw/esbuild#2335
helix Termux package helix-editor/helix#15694
uv Termux package; uv's CI also runs Termux integration tests against the linux-musl artifact astral-sh/uv#13845
oxlint Termux package
rollup Ships @rollup/rollup-android-arm64 via npm rollup/rollup#6089
starship Termux package starship/starship#6701
vite Works via rollup's android binary (rollup 4.52.2+) vitejs/vite#20766

I actually found that another user added a Termux package for turbo (termux/termux-packages#28773). I didn't think to look there because I was trying to pin turbo at the project level, given that mise doesn't really support Android without termux-chroot. I'll probably switch over to the Termux package in the meantime, but I still think there is precedent for Rust-as-npm-style projects shipping specific platform support.

gtbuchanan added a commit to gtbuchanan/tooling that referenced this pull request May 26, 2026
Restore `packageManager: pnpm@10.32.1` in package.json. Turbo's
workspace resolution requires that field and errors with
`Missing packageManager` without it — commit 6f773c7 should not
have dropped it. Adding it back fixes that latent regression.

Rather than mirror the pnpm pin between `mise.toml`'s `[tools]` and
`packageManager`, enable mise's `idiomatic_version_file_enable_tools
= ["pnpm"]` so mise reads the version straight from package.json's
`packageManager`. One pin, two consumers (turbo and mise). The aqua
backend still locks per-platform pnpm binaries in `mise.lock`; only
the version source moved.

AGENTS.md gains a `Why turbo isn't in mise.toml` section recording
why we don't manage turbo through mise (mise's only backend is
`npm:turbo`, no per-platform integrity in mise.lock, Vercel ships no
GitHub Release binaries today — though vercel/turborepo#12735 is the
live PR re-litigating that). CONTRIBUTING.md tells contributors that
Node and prek live in `mise.toml` while pnpm lives in
`packageManager`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support android

2 participants