Good evening,
I was messing around with the official Hermes agent Termux CLI and was able to successfully get it running despite some initial compiling issues I ran into from building via the Linux instructions. It's been running without major issues for me on my Android 13 phone, and I personally am loving the UI compared to theme readability issues I run into with even modified Termux CLIs. I'm posting this here as a summary of Hermes' work to hopefully provide some insight and future ideas if you want to make any changes to officially support how your project works/installs for Android.
As practically an amateur user, your mileage may vary on how safe and viable any of this is. Run at your own risk!
...
Date: 2026-07-13
Target: hermes_client (https://github.com/lotsoftick/hermes_client) on
Termux (aarch64 / Android 13, SDK 33), Node v26.3.1, npm 11.17.0
...
SUMMARY
hermes_client CAN run on Termux/Android, but the standard npm install +
npm run dev flow fails in three distinct ways due to (a) Termux having no
prebuilt native binaries for its bionic libc, and (b) a Termux-specific quirk
where npm strips node_modules/.bin (and /data/.../usr/bin) from the PATH of
package install/lifecycle scripts. All issues were resolved with workarounds;
no source code changes to hermes_client were required.
PROBLEM 1 — better-sqlite3 and bcrypt have no Termux prebuilt binaries
Symptom:
npm ERR! node-gyp ... better-sqlite3 ... build error
(and, separately, bcrypt fails at runtime: "No native build was found")
Cause:
- better-sqlite3@12.8.0 ships prebuilt binaries only for standard
linux-x64 / darwin / win32. On Termux (linux-aarch64-android, bionic libc)
no matching prebuilt exists, so it must compile from source.
- bcrypt ships prebuilts for linux-arm / linux-arm64 but ONLY as glibc/musl
flavors. Android uses bionic libc, so none of the prebuilts load. Worse,
bcrypt's install script is ONLY node-gyp-build (prebuilt lookup) with NO
node-gyp rebuild source-compile fallback — unlike better-sqlite3 which
falls back to node-gyp rebuild --release.
Fix (build both from source):
export GYP_DEFINES="android_ndk_path=''"
better-sqlite3:
cd ~/hermes_client/api/node_modules/better-sqlite3
node /data/data/com.termux/files/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js rebuild --release
bcrypt:
cd ~/hermes_client/api/node_modules/bcrypt
node /data/data/com.termux/files/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js rebuild --release
Notes:
- The critical env var is
GYP_DEFINES="android_ndk_path=''" — without it
node-gyp's build fails in Termux. This is documented in upstream
better-sqlite3 issue #857.
- The native compile on a phone takes ~10 minutes. Be patient.
- OpenSSL dev headers (needed by bcrypt) are present in the Termux package
set; ensure pkg install nodejs python make clang binutils is done first.
PROBLEM 2 — npm strips node_modules/.bin from lifecycle-script PATH
Symptom (during npm install):
npm error code 127
npm error path .../api/node_modules/bcrypt
npm error command sh -c node-gyp-build
npm error sh: 1: node-gyp-build: not found
(also appears for better-sqlite3-adjacent steps and for nodemon/vite)
Cause:
On this Termux environment, when npm runs a package's install/lifecycle
script (e.g. sh -c node-gyp-build, sh -c nodemon ..., sh -c vite),
the child shell's PATH does NOT include node_modules/.bin. Even installing
node-gyp-build globally (so it lives at /data/.../usr/bin/node-gyp-build)
does not help, because the script subshell also lacks the Termux bin dir on
its PATH. This causes a chicken-and-egg failure: every npm install aborts
on bcrypt's postinstall before node-gyp-build can be placed in .bin.
Fix that gets past it:
1. Download everything WITHOUT running install scripts (this is what
actually populates node_modules/.bin/node-gyp-build):
cd ~/hermes_client/api
rm -rf node_modules package-lock.json
npm install --ignore-scripts
2. Then run the native compiles directly (see Problem 1). npm rebuild
still fails here because of the same PATH issue, so invoke node-gyp by
ABSOLUTE path instead.
PROBLEM 3 — npm run dev cannot find nodemon / vite
Symptom:
[API] sh: 1: nodemon: not found
[CLIENT] sh: 1: vite: not found
(dev.js spawns npm run dev in api/ and client/, which invoke nodemon and
vite via sh -c; both fail for the same .bin-on-PATH reason as Problem 2.)
Additional wrinkle: the root node_modules/.bin/vite symlink is never created
because only api/ had npm install run (the root install was never done).
vite exists only as node_modules/vite/bin/vite.js at the repo root.
Fix (launch the two servers directly, bypassing npm scripts entirely):
export GYP_DEFINES="android_ndk_path=''"
export API_PORT=18889
export CLIENT_PORT=18888
export PATH="$HOME/hermes_client/api/node_modules/.bin:$HOME/hermes_client/node_modules/.bin:$PATH"
API:
cd ~/hermes_client/api
node ./node_modules/ts-node/dist/bin.js ./src/app.ts
Client (note: invoke vite.js by absolute path — the .bin symlink is absent):
cd ~/hermes_client/client
node ../node_modules/vite/bin/vite.js --host --port 18888
Other Termux gotchas hit along the way:
- ts-node's bin has a shebang
#!/usr/bin/env node; executing the .bin
script directly fails with "bad interpreter: /usr/bin/env: no such file
or directory" because Termux's env lives at a different path. Fix: run
ts-node THROUGH node (node ./node_modules/ts-node/dist/bin.js ...)
rather than executing the shebang script.
- nodemon CLI args containing a glob (
*.d.ts) are expanded by zsh and fail
with "no matches found"; avoid shell globbing in the command.
VERIFICATION (what "working" looks like)
- Client (Vite) serves HTTP 200 on http://localhost:18888
- API serves HTTP 301 (redirect to /api/docs/) on http://localhost:18889
(a 404 on / and 301 on /api/docs are both signs the server is up)
- Native artifacts present:
api/node_modules/better-sqlite3/build/Release/better_sqlite3.node
api/node_modules/bcrypt/build/Release/bcrypt_lib.node
- Default login: admin@admin.com / 123456
SUGGESTIONS FOR MAINTAINERS
- Termux/bionic has no prebuilt native binaries for better-sqlite3 or bcrypt.
Consider documenting the --ignore-scripts + source-build workaround, or
switching the API datastore to a pure-JS option to avoid native deps on
Termux entirely.
- npm on Termux does not expose node_modules/.bin to lifecycle scripts'
subshells. A script that launches servers via absolute binary paths (or
uses npm exec / npx) would be more portable than relying on npm run
resolving .bin in a child sh.
- The root project's
npm install does not install workspace deps (vite at
root, nodemon/ts-node in api/). Running install only in api/ leaves the
root .bin/vite symlink missing. Either document a full root install or make
dev.js resilient to missing .bin entries.
================================================================================
This report was produced while getting hermes_client running on a real
Termux/Android device. No source modifications were made; all fixes are
environment/launch workarounds.
Good evening,
I was messing around with the official Hermes agent Termux CLI and was able to successfully get it running despite some initial compiling issues I ran into from building via the Linux instructions. It's been running without major issues for me on my Android 13 phone, and I personally am loving the UI compared to theme readability issues I run into with even modified Termux CLIs. I'm posting this here as a summary of Hermes' work to hopefully provide some insight and future ideas if you want to make any changes to officially support how your project works/installs for Android.
As practically an amateur user, your mileage may vary on how safe and viable any of this is. Run at your own risk!
...
Date: 2026-07-13
Target: hermes_client (https://github.com/lotsoftick/hermes_client) on
Termux (aarch64 / Android 13, SDK 33), Node v26.3.1, npm 11.17.0
...
SUMMARY
hermes_client CAN run on Termux/Android, but the standard
npm install+npm run devflow fails in three distinct ways due to (a) Termux having noprebuilt native binaries for its bionic libc, and (b) a Termux-specific quirk
where npm strips node_modules/.bin (and /data/.../usr/bin) from the PATH of
package install/lifecycle scripts. All issues were resolved with workarounds;
no source code changes to hermes_client were required.
PROBLEM 1 — better-sqlite3 and bcrypt have no Termux prebuilt binaries
Symptom:
npm ERR! node-gyp ... better-sqlite3 ... build error
(and, separately, bcrypt fails at runtime: "No native build was found")
Cause:
linux-x64 / darwin / win32. On Termux (linux-aarch64-android, bionic libc)
no matching prebuilt exists, so it must compile from source.
flavors. Android uses bionic libc, so none of the prebuilts load. Worse,
bcrypt's install script is ONLY
node-gyp-build(prebuilt lookup) with NOnode-gyp rebuildsource-compile fallback — unlike better-sqlite3 whichfalls back to
node-gyp rebuild --release.Fix (build both from source):
export GYP_DEFINES="android_ndk_path=''"
better-sqlite3:
cd ~/hermes_client/api/node_modules/better-sqlite3
node /data/data/com.termux/files/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js rebuild --release
bcrypt:
cd ~/hermes_client/api/node_modules/bcrypt
node /data/data/com.termux/files/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js rebuild --release
Notes:
GYP_DEFINES="android_ndk_path=''"— without itnode-gyp's build fails in Termux. This is documented in upstream
better-sqlite3 issue #857.
set; ensure
pkg install nodejs python make clang binutilsis done first.PROBLEM 2 — npm strips node_modules/.bin from lifecycle-script PATH
Symptom (during
npm install):npm error code 127
npm error path .../api/node_modules/bcrypt
npm error command sh -c node-gyp-build
npm error sh: 1: node-gyp-build: not found
(also appears for better-sqlite3-adjacent steps and for nodemon/vite)
Cause:
On this Termux environment, when npm runs a package's install/lifecycle
script (e.g.
sh -c node-gyp-build,sh -c nodemon ...,sh -c vite),the child shell's PATH does NOT include node_modules/.bin. Even installing
node-gyp-build globally (so it lives at /data/.../usr/bin/node-gyp-build)
does not help, because the script subshell also lacks the Termux bin dir on
its PATH. This causes a chicken-and-egg failure: every
npm installabortson bcrypt's postinstall before node-gyp-build can be placed in .bin.
Fix that gets past it:
1. Download everything WITHOUT running install scripts (this is what
actually populates node_modules/.bin/node-gyp-build):
cd ~/hermes_client/api
rm -rf node_modules package-lock.json
npm install --ignore-scripts
2. Then run the native compiles directly (see Problem 1).
npm rebuildstill fails here because of the same PATH issue, so invoke node-gyp by
ABSOLUTE path instead.
PROBLEM 3 —
npm run devcannot find nodemon / viteSymptom:
[API] sh: 1: nodemon: not found
[CLIENT] sh: 1: vite: not found
(dev.js spawns
npm run devin api/ and client/, which invoke nodemon andvite via sh -c; both fail for the same .bin-on-PATH reason as Problem 2.)
Additional wrinkle: the root
node_modules/.bin/vitesymlink is never createdbecause only
api/hadnpm installrun (the root install was never done).vite exists only as node_modules/vite/bin/vite.js at the repo root.
Fix (launch the two servers directly, bypassing npm scripts entirely):
export GYP_DEFINES="android_ndk_path=''"
export API_PORT=18889
export CLIENT_PORT=18888
export PATH="$HOME/hermes_client/api/node_modules/.bin:$HOME/hermes_client/node_modules/.bin:$PATH"
API:
cd ~/hermes_client/api
node ./node_modules/ts-node/dist/bin.js ./src/app.ts
Client (note: invoke vite.js by absolute path — the .bin symlink is absent):
cd ~/hermes_client/client
node ../node_modules/vite/bin/vite.js --host --port 18888
Other Termux gotchas hit along the way:
#!/usr/bin/env node; executing the .binscript directly fails with "bad interpreter: /usr/bin/env: no such file
or directory" because Termux's env lives at a different path. Fix: run
ts-node THROUGH node (
node ./node_modules/ts-node/dist/bin.js ...)rather than executing the shebang script.
*.d.ts) are expanded by zsh and failwith "no matches found"; avoid shell globbing in the command.
VERIFICATION (what "working" looks like)
(a 404 on
/and 301 on/api/docsare both signs the server is up)api/node_modules/better-sqlite3/build/Release/better_sqlite3.node
api/node_modules/bcrypt/build/Release/bcrypt_lib.node
SUGGESTIONS FOR MAINTAINERS
Consider documenting the
--ignore-scripts+ source-build workaround, orswitching the API datastore to a pure-JS option to avoid native deps on
Termux entirely.
subshells. A script that launches servers via absolute binary paths (or
uses
npm exec/npx) would be more portable than relying onnpm runresolving .bin in a child sh.
npm installdoes not install workspace deps (vite atroot, nodemon/ts-node in api/). Running install only in api/ leaves the
root .bin/vite symlink missing. Either document a full root install or make
dev.js resilient to missing .bin entries.
================================================================================
This report was produced while getting hermes_client running on a real
Termux/Android device. No source modifications were made; all fixes are
environment/launch workarounds.