{"id":30948230,"url":"https://github.com/tribixbite/bun-on-termux","last_synced_at":"2026-04-02T03:04:34.364Z","repository":{"id":310600168,"uuid":"1040303948","full_name":"tribixbite/bun-on-termux","owner":"tribixbite","description":"Native Bun JavaScript runtime working on Termux Android using glibc-runner","archived":false,"fork":false,"pushed_at":"2026-03-13T04:34:49.000Z","size":61669,"stargazers_count":14,"open_issues_count":2,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-13T08:41:52.220Z","etag":null,"topics":["android","arm64","bun","glibc-runner","javascript","runtime","termux","typescript"],"latest_commit_sha":null,"homepage":"https://bun.termux.party","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tribixbite.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-18T19:10:50.000Z","updated_at":"2026-03-13T04:34:53.000Z","dependencies_parsed_at":"2025-08-19T06:25:59.697Z","dependency_job_id":null,"html_url":"https://github.com/tribixbite/bun-on-termux","commit_stats":null,"previous_names":["tribixbite/bun-on-termux"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/tribixbite/bun-on-termux","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tribixbite%2Fbun-on-termux","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tribixbite%2Fbun-on-termux/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tribixbite%2Fbun-on-termux/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tribixbite%2Fbun-on-termux/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tribixbite","download_url":"https://codeload.github.com/tribixbite/bun-on-termux/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tribixbite%2Fbun-on-termux/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31294832,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T01:43:37.129Z","status":"online","status_checked_at":"2026-04-02T02:00:08.535Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","arm64","bun","glibc-runner","javascript","runtime","termux","typescript"],"created_at":"2025-09-11T02:02:17.959Z","updated_at":"2026-04-02T03:04:34.353Z","avatar_url":"https://github.com/tribixbite.png","language":"Shell","funding_links":[],"categories":["Shell"],"sub_categories":[],"readme":"# Bun on Termux\n\nRun [Bun](https://bun.sh) natively on Android via [Termux](https://termux.dev) using a C userland exec wrapper + LD_PRELOAD shim.\n\n**Current version**: Bun v1.3.10 (linux-aarch64 glibc) on Android ARM64.\n\n## How it works\n\nBun is a glibc binary. Android uses bionic libc. This project provides:\n\n1. **`bun-termux` (C wrapper)** — loads glibc's `ld-linux-aarch64.so.1` via userland exec, passing environment variables natively through the constructed stack\n2. **`bun-shim.so` (LD_PRELOAD shim)** — intercepts filesystem syscalls to work around Android's restricted directory access\n3. **`bun` (bash wrapper)** — handles argument routing, package.json script parsing, and `--cwd`/`--backend` injection\n\n### Architecture\n\n```\nbun (bash wrapper) -\u003e bun-termux (C) -\u003e ld.so -\u003e bun-shim.so -\u003e buno (real binary)\n     |                    |                          |\n     |                    |                    intercepts: openat, stat,\n     |                    |                    access, execve, /proc/stat\n     |                    |\n     |               userland exec:\n     |               - maps ld.so ELF segments\n     |               - constructs stack (argv/envp/auxv)\n     |               - passes env vars natively\n     |               - filters LD_PRELOAD/LD_LIBRARY_PATH\n     |\n     handles: argument parsing, package.json scripts,\n     --cwd injection, --backend=copyfile for pkg mgmt\n```\n\n### What the shim intercepts\n\n| Syscall | Purpose |\n|---------|---------|\n| `openat`/`openat64`/`open`/`open64` | Redirect `/proc/stat` (fake CPU info for `os.cpus()`), redirect `O_DIRECTORY` reads of `/`, `/data`, `/storage` to safe dir |\n| `stat`/`lstat`/`fstatat` | Synthesize directory stats for restricted paths (`fs.existsSync`, `fs.statSync`) |\n| `access`/`faccessat` | Intercept permission checks on restricted paths |\n| `execve` | Parse shebangs, translate `/usr/bin` -\u003e `$PREFIX/bin` |\n| `link`/`linkat` | Fall back to copy when hardlinks fail (Android f2fs) |\n\n## Quick start\n\n### Prerequisites\n\n- **Termux** from F-Droid or GitHub (not Play Store)\n- **termux-pacman** package manager (not apt/pkg)\n- **glibc-runner**: `pacman -S glibc-runner`\n- **clang**: `pkg install clang` (for building C components)\n- **ARM64 (aarch64)** device\n\n### Install\n\n```bash\ngit clone https://github.com/tribixbite/bun-on-termux.git\ncd bun-on-termux\nmake install\nchmod +x setup.sh \u0026\u0026 ./setup.sh\n```\n\nOr manually:\n\n```bash\nmkdir -p ~/.bun/{bin,lib,tmp/fake-root}\n\n# Build and install C components\nmake all\ncp bun-termux ~/.bun/bin/\ncp bun-shim.so ~/.bun/lib/\n\n# Copy wrapper and config\ncp wrappers/bun ~/.bun/bin/bun-minimal\nln -sf bun-minimal ~/.bun/bin/bun\ncp config/bunfig.toml ~/.bun/bin/\n\n# Download bun binary\nBUN_VERSION=\"1.3.10\"\ncurl -fsSL \"https://github.com/oven-sh/bun/releases/download/bun-v${BUN_VERSION}/bun-linux-aarch64.zip\" \\\n  -o ~/.bun/tmp/bun.zip\nunzip -o ~/.bun/tmp/bun.zip -d ~/.bun/tmp/\ncp ~/.bun/tmp/bun-linux-aarch64/bun ~/.bun/bin/buno\nchmod +x ~/.bun/bin/buno ~/.bun/bin/bun-termux\n\n# Add to PATH\necho 'export PATH=\"$HOME/.bun/bin:$PATH\"' \u003e\u003e ~/.bashrc\nsource ~/.bashrc\n\n# Verify\nbun --version\n```\n\n## What works\n\n| Feature | Status | Notes |\n|---------|--------|-------|\n| `bun --version` | works | Passthrough to binary |\n| `bun script.ts` | works | Native TypeScript execution |\n| `bun script.js` | works | Direct file execution |\n| `bun run \u003cscript\u003e` | works | Wrapper parses package.json |\n| `bun install` | works | `copyfile` backend, auto `--cwd` |\n| `bun add \u003cpkg\u003e` | works | Local and global |\n| `bun test` | works | Test runner with fixture discovery |\n| `bun build` | works | Bundler with all flags |\n| `bun build --compile` | works | ~14KB output (embeds wrapper, not full runtime) |\n| `bun -e '\u003ccode\u003e'` | works | Inline eval |\n| `bun repl` | works | Interactive REPL |\n| `bunx \u003cpkg\u003e` | works | Package execution |\n| `process.env.*` | works | Passed natively via C wrapper |\n| `os.cpus()` | works | Shim spoofs `/proc/stat` |\n| `Bun.serve()` | works | HTTP + WebSocket servers |\n| `bun:sqlite` | works | Native SQLite binding |\n| Workers | works | `new Worker()` threads |\n| `Bun.spawn()` | works | Child process execution |\n| `bun init` | works | Blank + React project templates |\n| `bun create` | works | Vite, Astro templates via bunx |\n\n## Known limitations\n\n- **`bun build --compile` output**: Compiled binaries are ~14KB (embed the wrapper, not buno). They run on any Termux+glibc-runner device with buno + bun-shim.so installed, but are not standalone on non-Termux systems.\n- **LD_PRELOAD scope**: Bun uses raw syscalls for JS-level file I/O (`fs.readFileSync`, `fs.statSync`), bypassing the shim. Shim interceptions only apply to glibc-internal operations (directory traversal, /proc reads, shebangs, hardlinks).\n- **`fs.watch()`**: May not trigger reliably on all Android kernels due to inotify restrictions.\n- **Platform detection**: Bun reports `linux-arm64` instead of `android-arm64`. Optional native binaries like `@rollup/rollup-android-arm64` must be installed via `npm install` if needed.\n- **bash wrapper overhead**: Package.json parsing adds ~50-150ms startup overhead from fork/exec. Future v2 may port argument routing to C.\n\n## Comparison with other Termux Bun projects\n\nThis project builds on techniques from two reference implementations. See [docs/COMPARISON.md](docs/COMPARISON.md) for full details.\n\n|  | **bun-on-termux** | **bun-termux** | **bun-termux-loader** |\n|--|-------------------|----------------|----------------------|\n| **Repo** | [tribixbite/bun-on-termux](https://github.com/tribixbite/bun-on-termux) | [Happ1ness-dev/bun-termux](https://github.com/Happ1ness-dev/bun-termux) | [kaan-escober/bun-termux-loader](https://github.com/kaan-escober/bun-termux-loader) |\n| **Approach** | Bash wrapper + C wrapper + shim | C wrapper + shim | Embedded binary + shim |\n| **Bun binary** | External (`buno`) | External (`buno`) | Embedded (~92MB self-contained) |\n| **Userland exec** | Yes | Yes | Yes |\n| **`/proc/self/exe`** | Preserved | Preserved | Preserved |\n| **Shim syscalls** | openat, stat, access, execve, link | openat, execve | dlopen |\n| **`os.cpus()`** | Works (shim spoofs `/proc/stat`) | Works (shim spoofs `/proc/stat`) | N/A |\n| **`fs.existsSync('/')`** | Works (stat interception) | Errors | Errors |\n| **Hardlink fallback** | Auto copy via link/linkat shim | Manual `--backend=copyfile` | Manual `--backend=copyfile` |\n| **Shebang translation** | Auto (`/usr/bin` -\u003e `$PREFIX/bin`) | Auto (`/usr/bin` -\u003e `$PREFIX/bin`) | None |\n| **Bash wrapper** | Yes (arg routing, pkg.json, --cwd) | None | None |\n| **`bun run \u003cscript\u003e`** | Parses package.json | Passthrough to bun | N/A |\n| **`bun install`** | Auto --cwd + --backend | Manual flags needed | N/A |\n| **`bun init` / `bun create`** | Works (shim + wrapper) | Manual workarounds | N/A |\n| **Compiled binaries** | Works (same device) | Works + replace_runtime.py | Works (self-contained) |\n| **Test suite** | 80 tests, 18 categories | 8 tests | None |\n| **Build tool** | Makefile (clang) | Makefile (clang) | Makefile + Python |\n\n## Test suite\n\nRun the comprehensive test suite (80 tests across 18 categories):\n\n```bash\nbash tests/run-tests.sh\n```\n\nFilter by category or pattern:\n\n```bash\nbash tests/run-tests.sh --category K        # Bun APIs only\nbash tests/run-tests.sh --filter \"sqlite\"   # Pattern match\n```\n\nCategories: A=CLI, B=FileExec, C=Eval, D=REPL, E=TestRunner, F=Build, G=PkgMgmt, H=Scripts, I=Bunx, J=Create, K=BunAPIs, L=EnvVars, M=LowLevel, N=DevServer, O=Network, P=Workers, Q=FFI, R=Stress\n\n## File structure\n\n```\n~/.bun/\n  bin/\n    bun           -\u003e bun-minimal (symlink)\n    bun-minimal   \u003c- bash wrapper script\n    bun-termux    \u003c- C userland exec wrapper\n    buno          \u003c- real bun binary (official release)\n    bunfig.toml   \u003c- bun config\n  lib/\n    bun-shim.so   \u003c- LD_PRELOAD interception shim\n  tmp/\n    fake-root/    \u003c- safe directory for shim redirects\n  install/\n    cache/        \u003c- package download cache\n```\n\n## Repository layout\n\n```\nbun-on-termux/\n  src/\n    bun-termux.c  \u003c- C wrapper (userland exec)\n    shim.c        \u003c- LD_PRELOAD shim\n  wrappers/\n    bun           \u003c- main wrapper script\n    bunx          \u003c- bunx wrapper (delegates to bun x)\n    env-preload.js \u003c- legacy preload (kept as fallback)\n  tests/\n    run-tests.sh  \u003c- test runner (80 tests)\n    lib/          \u003c- shared test helpers\n    fixtures/     \u003c- test fixture files\n  config/\n    bunfig.toml   \u003c- global bun configuration\n  helper_scripts/\n    replace-runtime.py \u003c- swap runtime in compiled binaries\n  docs/\n    ARCHITECTURE.md\n    COMPARISON.md\n    TROUBLESHOOTING.md\n    ...\n  Makefile        \u003c- build system\n  setup.sh        \u003c- automated installer\n```\n\n## Upgrading bun\n\n```bash\n# Download specific version\nbash scripts/download-official-bun.sh 1.3.10\n\n# Or manually\ncp ~/.bun/bin/buno ~/.bun/bin/buno.$(bun --version).bak\nBUN_VERSION=\"1.3.10\"\ncurl -fsSL \"https://github.com/oven-sh/bun/releases/download/bun-v${BUN_VERSION}/bun-linux-aarch64.zip\" \\\n  -o ~/.bun/tmp/bun.zip\nunzip -o ~/.bun/tmp/bun.zip -d ~/.bun/tmp/\ncp ~/.bun/tmp/bun-linux-aarch64/bun ~/.bun/bin/buno\nchmod +x ~/.bun/bin/buno\nbun --version\n```\n\nUse `bun-linux-aarch64.zip` (glibc variant), not musl.\n\n## Docs\n\n- [Architecture](docs/ARCHITECTURE.md)\n- [Comparison](docs/COMPARISON.md) — feature comparison with other Termux Bun projects\n- [Troubleshooting](docs/TROUBLESHOOTING.md)\n- [Installation](docs/INSTALLATION.md)\n- [Binary Compatibility](docs/BINARY-COMPATIBILITY.md)\n- [Termux Config](docs/TERMUX_CONFIG.md)\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftribixbite%2Fbun-on-termux","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftribixbite%2Fbun-on-termux","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftribixbite%2Fbun-on-termux/lists"}