DEV Community

Cover image for From a 4-Year-Old Feature Request to `pkg install bun`: My Second Merge on the Termux User Repository
Gouranga Das Samrat
Gouranga Das Samrat

Posted on

From a 4-Year-Old Feature Request to `pkg install bun`: My Second Merge on the Termux User Repository

Last post i wrote was about getting turned away from the main repo over a policy disagreement and landing my first TUR merge instead with 8 Nerd Fonts packages.

This is the same shape of story again, except the "no" from the main repo wasn't about repo size this time — it was about something much harder to argue around: how Termux insists packages get built.

An issue older than some of the tools people used to work around it

Issue #11188 asking for bun in Termux goes back to July 2022, opened by @leap0x7b. Reading the whole thread back to front is basically a history of people improvising around a missing package for four straight years:

  • Early on, bun's Linux aarch64 build just didn't run on Android — npm install -g bun failed outright with an EBADPLATFORM error, because upstream hadn't shipped an Android target.
  • The workaround that kept surfacing was grun, a glibc compatibility shim, letting people run the Linux binary against a glibc environment layered on top of Termux's normal Bionic libc. It mostly worked, with recurring reports of install failures (AccessDenied errors from bun install trying to hardlink files) and one-off fixes like bun install --backend=copyfile.
  • A few people tried building bun from source directly. That hit its own wall: Bun's own docs state that Bun itself must be installed to compile Bun — you need an existing bun binary just to build a new one — plus a strict Zig version dependency that broke against whatever Termux had packaged at the time.
  • @TomJo2000 summed up the stall bluntly in mid-2025: nobody had written a build script, no other distro built it from source either, and it depended on a kernel version most Android devices didn't meet.

The turn came in April 2026, when @licy183 flagged that upstream had finally added an Android build target. @TomJo2000 noted the obvious next step — someone still had to actually write the build script. By mid-May, @Jobians confirmed Bun was running natively using the official Android ARM64 build. The pieces were finally there. I decided to be the one to write the script.

Round one: prebuilt binaries, meet main-repo policy

I opened termux-packages PR #31115addpkg(main/bun): 1.3.14 — built around the official prebuilt Android binaries that shipped in Bun v1.3.14. The binaries are Position-Independent Executables linked straight against standard Bionic libraries (libc.so, libm.so, libdl.so), so no glibc shim needed at all — a real fix for the grun workaround people had been leaning on for years. The only real limitation was architecture: upstream only builds Android targets for aarch64 and x86_64, so I set those two as excluded-safe and expected arm/i686 to just skip cleanly in CI.

@robertkirkman stopped that approach at the door: termux-packages requires compiling from source, so downloading upstream's prebuilt binaries wasn't going to fly. He floated a specific alternative — if Bun were published as an installable crate on crates.io, cargo-binstall could fetch upstream binaries in a way the main repo's tooling already sanctions. Worth checking, but it didn't pan out: Bun isn't a simple Rust crate at all. It's a monorepo built through its own CMake pipeline, linking against JavaScriptCore/WebKit and LLVM — nothing cargo build --release or cargo-binstall can touch.

There was a fun tangent buried in the same exchange — @robertkirkman noting Node.js is already built from source in Termux and reasoning Bun should in theory be possible too, then wondering out loud whether Bun is meaningfully faster than both Node and Deno (Deno also being a from-source build in Termux) — the kind of "is this actually a different tool or just a faster clone" curiosity that comes up naturally whenever a runtime like this gets proposed.

I went and actually tried the from-source route properly, then came back and closed the PR myself on August 20 with a detailed writeup of exactly where it broke down:

  • Bun's build system does have official Android cross-compile support (--abi=android, --android-ndk=<path>), confirmed against the pattern in its .buildkite/Dockerfile (NDK r27c, host-clang + sysroot).
  • WebKit doesn't need a from-source build for Android — a prebuilt tarball gets fetched automatically, so that wasn't the blocker I expected.
  • The actual wall was a statically, cross-compiled ICU for Android ($BUN_ANDROID_ICU_ROOT) with no public build recipe I could find anywhere — not in oven-sh/bun, not in oven-sh/bun-development-docker-image, not in the actual .buildkite/Dockerfile, despite a comment in webkit.ts pointing at a "Dockerfile.android" that doesn't seem to exist publicly.

Add a strictly pinned LLVM 21.1.8 and a pinned Rust nightly on top of that, and it was more toolchain archaeology than I could commit to finishing in one PR. So I closed it, thanked @robertkirkman for the guidance, and left the door open to revisit if upstream's Android/ICU story ever gets easier to build from source.

The TUR side already had its own long-running Bun request

There was already a parallel thread for this on TUR: tur issue #571, opened back in 2023 by @earningpoints. @licy183 had kept it open rather than closing it outright, citing two blockers at the time — Bun's kernel 5.1 requirement, which most Android devices didn't meet, and the fact that it didn't compile against non-glibc libcs like musl. @jothi-prasath tried getting it running via grun and shared a working build script, but @licy183 was clear about where TUR draws its own line: binaries in TUR packages need to link against Bionic libc, not GNU libc, with no plan to support a custom-loader GNU libc setup.

That distinction turned out to matter a lot for round two — because the whole reason the official Bun v1.3.14 Android binaries worked for Termux at all is that they're linked directly against Bionic. No grun, no glibc shim, no custom loader path. They fit TUR's actual requirement perfectly; they just didn't fit the main repo's from-source rule.

Round two: TUR PR #2746

I opened tur PR #2746 — same package, same version, same prebuilt-binary approach — explicitly closing both threads at once: Fixes termux/termux-packages#11188 #571, with a note that it was migrated from PR #31115 specifically because of the main repo's build-from-source policy. No repeat of the source-vs-prebuilt argument — TUR's policy is built for exactly this kind of package.

Review was quick and purely technical. @licy183 caught an inefficiency in build.sh: rather than my approach, the more common pattern is to download binaries for both aarch64 and x86_64 up front and only install the one matching the build architecture — pointing me at how pypy3's build script already does it. I made the change same day. A second review comment flagged that my binary-path handling was split oddly across build steps — it only needed to run in termux_step_make_install, while termux_step_post_get_source should just be fetching the LICENSE file. I moved the logic accordingly.

Then: a simple "Thanks!" from @licy183, and that was that.

What changed, twice over

The version string says 1.3.14, same as the PR I closed on the main repo, but what actually shipped is bigger than the number:

  • A four-year-old feature request that survived grun hacks, glibc shims, Zig version breakage, and a genuine "you need Bun to build Bun" chicken-and-egg problem, finally resolved with pkg install bun.
  • A real technical answer, on the record, for why termux-packages couldn't take it as-is: a from-source Android build is blocked on a static cross-compiled ICU with no public recipe — useful for whoever eventually revisits it.
  • Confirmation from TUR's side of exactly which binaries are acceptable there: Bionic-linked, no glibc shim required — which is exactly what upstream Bun now ships.

Two PRs in a row now where the front door said no for a real, defensible reason, and TUR turned out to be exactly the right back door. Different reasons each time — repo-size policy for the fonts, source-build policy for Bun — but the same shape of resolution. I'm starting to think that's just what TUR is for.

Get it

If you're on Termux and TUR isn't already added as a repo, three commands and bun is installed with no grun, no glibc shim, none of the workarounds from that four-year thread:

pkg install tur-repo
pkg update
pkg install bun
Enter fullscreen mode Exit fullscreen mode

Proof it's live:

~ $ pkg show bun
Package: bun
Version: 1.3.14-1
Maintainer: Gouranga Das Samrat <gouranga.das.khulna@gmail.com>
Installed-Size: 89.8 MB
Homepage: https://bun.com
Download-Size: 22.8 MB
APT-Sources: https://tur.kcubeterm.com tur-packages/tur aarch64 Packages
Description: Incredibly fast JavaScript runtime, bundler, test runner, and package manager
Enter fullscreen mode Exit fullscreen mode

The full trail:

Top comments (0)