Hack #6 moved the npm cache to the SD card (/sdcard/npm-cache) to free internal storage. This worked for most packages, but git-based dependencies caused intermittent failures. When npm resolves a dependency from a git URL (e.g., github:user/repo#branch), it clones the repository into the cache directory, creating deep .git/objects/ hierarchies with paths like:
/sdcard/npm-cache/_cacache/content-v2/sha512/ab/cd/.git/objects/pack/pack-abc123...456.idxThese paths easily exceed the 255-character limit imposed by FAT32 via Android's sdcardfs FUSE layer. The result is ENAMETOOLONG errors that cause npm install to fail midway, leaving a corrupted cache that requires manual cleanup.
The /data partition where Termux lives is ext4, which supports path components up to 255 characters each and total paths limited only by the kernel's PATH_MAX of 4096 characters. Moving the cache there eliminates the problem entirely.
This hack supersedes Hack #6 (npm cache on SD card).
Inside the proot Ubuntu rootfs (or native Termux, same principle):
# Set npm cache to a directory on the ext4 /data partition
npm config set cache /root/.npm-cache
# Create the directory
mkdir -p /root/.npm-cache
# Verify the new setting
npm config get cache
# Expected: /root/.npm-cache
# Clean the old SD card cache (optional, frees SD card space)
rm -rf /sdcard/npm-cacheFor the native Termux setup (post proot migration):
# Native Termux equivalent — cache inside Termux's home
npm config set cache $HOME/.npm-cache
# Or use a path under $PREFIX/tmp for ephemeral caching
npm config set cache $PREFIX/tmp/.npm-cacheTo verify the cache location is being used during installs:
# Run an install and watch where cache files land
npm install -g openclaw --ignore-scripts --legacy-peer-deps --cache /root/.npm-cache
# Check cache contents after install
ls /root/.npm-cache/
# Expected: _cacache/ _logs/ _npx/ etc.
# Check cache size
du -sh /root/.npm-cache/
# Expected: 200-400 MB depending on packages installed# Confirm npm is configured correctly:
npm config get cache
# Expected: /root/.npm-cache (or $HOME/.npm-cache)
# Test with a git dependency that previously failed on FAT32:
npm cache clean --force
npm install some-git-dep@github:user/repo --cache /root/.npm-cache
# Expected: installs without ENAMETOOLONG
# Verify no files remain on SD card:
ls /sdcard/npm-cache 2>&1
# Expected: "No such file or directory" (if cleaned)
# Check filesystem type to confirm ext4:
mount | grep /data
# Expected: /dev/block/... on /data type ext4 .../data has enough free space before switching. On the Moto E2 with 4 GB internal, this requires careful space management alongside the rootfsnpm config set cache writes to ~/.npmrc. If you use both proot and native Termux, each environment has its own .npmrc — set the cache path in bothnpm cache clean --force before the migration prevents carrying over any corrupted entries from the FAT32 eranpm cache clean --force after installs are complete. The cache is only needed during npm install, not at runtime/root/ path doesn't exist. Use $HOME/.npm-cache or $PREFIX/tmp/.npm-cache instead| Metric | SD Card (FAT32) | Rootfs (ext4) |
|---|---|---|
| Max path length | 255 chars (FAT32 limit) | 4096 chars (PATH_MAX) |
| Git dependencies | ENAMETOOLONG failures | Works reliably |
| Symlink support | Not supported | Full support |
| I/O speed | ~10-20 MB/s | ~50-100 MB/s |
| npm install reliability | Intermittent failures | Consistent |
| Cache location | /sdcard/npm-cache | /root/.npm-cache |