ios-linuxkit is an ARM64 Linux runtime for iOS projects. It builds on the ish-arm64 work in iSH and focuses on a testable guest environment for shells, package managers, compilers, language runtimes, and CLI tooling on iPhone and iPad.
The terminal app in this repository is a reference shell. The reusable parts are the ARM64 guest runtime, syscall/filesystem/network compatibility work, and the Linux-host test harnesses used to keep regressions visible.
| Goal | Current shape |
|---|---|
| iOS-safe execution | iSH Asbestos threaded-code interpreter; no runtime code generation, RWX memory, or MAP_JIT. |
| ARM64 Linux guest | AArch64 guest support with a 48-bit guest address space for V8, JavaScriptCore, Go, Rust, JVM, and similar runtimes. |
| Reproducible testing | Linux-host harnesses boot the same ARM64 fakefs used for iOS work, so syscall/runtime failures can be reproduced outside Xcode. |
| Runtime coverage | Shell, apk, C/C++, Go, Rust/Cargo, Bun, Node/npm, Python, Lua, Java/OpenJDK, Clojure, Erlang, Zig, C# NativeAOT availability, and CLI smoke rows. |
| iOS terminal sample | Ghostty-Web frontend with Fira Code Nerd Font, Kitty graphics support, hardened ObjC/JS bridge handling, and validated theme/font paths. |
| Gate | Result | Notes |
|---|---|---|
| Core runtime coverage | 83 / 83 passing | Alpine ARM64 fakefs; no SAFETY-VALVE or NETDIAG diagnostics in the latest report. |
| npm CLI package lane | 16 / 16 passing | Kept separate because npm packages move quickly. |
| CLI corner-case smoke | 57 pass / 2 unsupported / 0 fail | Wiki-derived CLI probes pass; dig DNS now uses real UDP successfully; Docker daemon/container rows remain unsupported for known runtime/kernel limitations. |
| Benchmarks Game rows | 10 / 10 per row | GCC, G++, Go, Python, Node.js, PHP, Perl, Ruby, Lua. |
| Java-equivalent Benchmarks Game | 10 / 10 | Mixed-mode and interpreter fallback both pass. |
See runtime validation for commands, reports, and failure rules. See workload smoke tests for heavier workload coverage.
Speculative ARM64 hot-trace instrumentation was attempted and then removed after it failed to show significant gains relative to its maintenance and runtime overhead. Current retained speed work is limited to validated block chaining/prechain and internal-continue paths; optional ISH_ARM64_BLOCK_STATS=1 diagnostics report those retained counters only.
The current Linux-host reports were produced on this board:
| Component | Detail |
|---|---|
| Board | Orange Pi 6 Plus |
| SoC | CIX P1 (CD8180/CD8160), ARMv8 AArch64 |
| CPU | 12 cores: 4× Cortex-A520 up to 1.8 GHz, 8× Cortex-A720 up to 2.6 GHz |
| RAM | 16 GB class; about 14 GiB visible to Linux |
| Storage | AirDisk 512 GB NVMe; root on /dev/nvme0n1p2, swap on /dev/nvme0n1p3 |
| OS/kernel | Orange Pi 1.0.2 Trixie / Debian Trixie, Linux 6.6.89-cix, aarch64 |
| Toolchain | Clang 19.1.7, Meson 1.7.0, Ninja 1.12.1, GNU Make 4.4.1 |
| Workflow | Command |
|---|---|
| Build Linux ARM64 variants | make build-arm64-linux-all |
| Core runtime gate | make test-arm64-runtime-coverage ROOTFS_LANES=alpine=$(pwd)/alpine-arm64-fakefs REPORT_DIR=/workspace/tmp TIMEOUT_S=180 INSTALL_TIMEOUT_S=1200 |
| CLI corner cases | make test-arm64-cli-corner-smoke ROOTFS_LANES=alpine=$(pwd)/alpine-arm64-fakefs REPORT_DIR=/workspace/tmp TIMEOUT_S=240 INSTALL_TIMEOUT_S=1200 |
| npm CLI package lane | make test-arm64-npm-cli-runtime-coverage ROOTFS_LANES=alpine=$(pwd)/alpine-arm64-fakefs REPORT_DIR=/workspace/tmp TIMEOUT_S=180 INSTALL_TIMEOUT_S=1800 |
| Node/Bun timing table | make test-arm64-node-bun-perf ROOTFS_LANES=alpine=$(pwd)/alpine-arm64-fakefs REPORT_DIR=/workspace/tmp TIMEOUT_S=180 |
Generated reports are Markdown files under REPORT_DIR. A row is not a pass if it times out, is force-killed, or emits diagnostics the harness classifies as runtime failure.
| Question | Short answer |
|---|---|
| Why not upstream iSH as-is? | The legacy i386 guest limits address space and runtime compatibility. This fork is ARM64-only and targets ARM-on-ARM interactive use. |
| Is this an App Store product? | No. The checked-in app is a reference terminal and packaging harness. |
| Why rename it? | To avoid confusion with upstream iSH and make the runtime-kit goal explicit. |
- docs/README.md — documentation map.
- docs/RUNTIME_VALIDATION.md — gates, commands, coverage areas, failure rules.
- docs/ARM64_WORKLOAD_SMOKE_TESTS.md — heavier workload matrix.
- docs/ARM64_BACKEND.md — ARM64 backend architecture notes.
- docs/LINUX_BUILD_AND_HOST_ABI.md — Linux-host build/platform notes.
- docs/ORIGINAL_ISH_README.md — preserved upstream/fork README material.
ios-linuxkit builds on iSH and ish-app/ish: user-mode Linux syscall translation, fakefs/realfs, the iOS app shell, and the Asbestos threaded-code interpreter. The ARM64 backend and runtime hardening come from the ish-arm64 fork work in this repository. Legacy upstream README material is preserved under docs/ and docs/legacy/.
See LICENSE.md and LICENSE.IOS.