Termux's native Node.js package on the apt-android-5 repo is version 12, which is far too old for OpenClaw (requires Node 18+). Inside the proot Ubuntu environment, the standard approach would be apt install nodejs, but dpkg frequently breaks inside proot due to filesystem syscall emulation issues (fakeroot conflicts, dpkg lock failures, statx syscall not intercepted properly).
The solution is to skip package managers entirely and use the pre-compiled binary tarball from nodejs.org. Node.js provides official linux-armv7l builds that include the V8 engine, npm, and full ICU data. These run on the Moto E2's Snapdragon 410 (Cortex-A53 cores operating in 32-bit ARMv7 mode).
This hack is marked LEGACY. The proot Node.js was replaced by a custom-compiled node22-icu binary running natively on Termux (58 MB, stripped, NDK r26c, API 24 with small-icu). See hack 12 for the native compilation story.
Download and extract Node.js 22 inside the proot rootfs:
# From inside proot (run-proot.sh)
cd /root
# Download the official ARM binary tarball
curl -L -o node-v22.12.0-linux-armv7l.tar.xz \
"https://nodejs.org/dist/v22.12.0/node-v22.12.0-linux-armv7l.tar.xz"
# Verify the SHA256 checksum matches nodejs.org/dist/v22.12.0/SHASUMS256.txt
sha256sum node-v22.12.0-linux-armv7l.tar.xzExtract and install to /usr/local:
# Extract the tarball
tar -xf node-v22.12.0-linux-armv7l.tar.xz
# Copy all contents to /usr/local (bin/, lib/, include/, share/)
cp -r node-v22.12.0-linux-armv7l/* /usr/local/
# Clean up the tarball and extracted directory
rm -rf node-v22.12.0-linux-armv7l node-v22.12.0-linux-armv7l.tar.xzVerify the installation:
node --version
# v22.12.0
npm --version
# 10.x.x
# Confirm ICU is included (needed for Unicode property escapes \p{L} \p{N})
node -e "console.log(Intl.DateTimeFormat('fr').format(new Date()))"
# Should print a French-formatted date
# Confirm architecture
node -e "console.log(process.arch, process.platform)"
# arm linuxSet the V8 heap limit to survive on 1 GB RAM:
# In /root/.openclaw/env or the start script
NODE_OPTIONS="--max-old-space-size=128"The binary can also be invoked from Termux through the proot helper:
# From Termux (outside proot)
run-proot.sh -c "node --version"
run-proot.sh -c "node /root/.openclaw/gateway/dist/index.js"node --version inside proot returns v22.12.0.node -e "console.log(process.arch)" returns arm.node -e "console.log(/\p{L}/u.test('e'))" returns true (Unicode property escapes work, confirming ICU is present).file /usr/local/bin/node shows ELF 32-bit LSB executable, ARM, EABI5.npm install of a small package succeeds inside proot.node -e "console.log(process.versions)" shows v8, icu, unicode versions.linux-armv7l build is the correct one, not linux-arm64. Even though the Cortex-A53 supports ARMv8/AArch64, the Moto E2 runs a 32-bit Android kernel and userspace. Using the arm64 binary results in exec format error.\p{L} and \p{N} Unicode property escapes in regular expressions. A --without-intl build would crash with "Invalid regular expression" errors at runtime.--max-old-space-size=96 causes OOM. The native migration later proved 112 MB is the true minimum (128 had been used in proot with some margin).stat() calls, is particularly affected.node-v22.12.0-linux-armv7l/ directory containing bin/, lib/, include/, and share/. Using tar -xf without --strip-components=1 -C /usr/local creates a nested directory. The cp -r approach shown above is more explicit./usr/local. This works because Node was extracted there. If extracted elsewhere, npm config set prefix /path/to/node is needed.--with-intl=small-icu to save space while still supporting \p{L} patterns.Node.js 22.12.0 runs inside proot on the Moto E2, providing a modern JavaScript runtime capable of running OpenClaw. The binary download approach completely bypasses all package manager issues. Combined with the run-proot.sh helper (hack 7) and V8 heap limits, this gave the phone a working OpenClaw gateway at roughly 170 MB RSS (including proot overhead). The native migration later reduced this to 155 MB by eliminating proot entirely and using a custom-compiled binary with small-icu.