Android (Termux)
sct runs on Android under Termux on 64-bit (aarch64) devices. This is
not a supported platform - there is no CI for it and no Android release target - but the
published linux-aarch64 binary works, with one significant limitation covered below.
Local work is the realistic use case: carrying a built snomed.db around and querying it
offline. A full RF2 build on a phone does work - see the options below - but it is slow, and
the published binary cannot download a release at all without a workaround.
Install Termux from F-Droid or GitHub, not the Play Store
Use the F-Droid build or a GitHub release. The Google Play build is a separate, experimental branch maintained in a different repository, described by the Termux maintainers as having "extensive adjustments in order to pass policy requirements there" along with "missing functionality and bugs" - their own recommendation is F-Droid or GitHub. Running a downloaded native binary is among the things that does not reliably work on the Play Store build.
Do not mix sources: Termux and its plugins must all come from the same one, or Android will refuse to install them together.
Install sct
pkg install curl
curl -fsSL https://raw.githubusercontent.com/pacharanero/sct/main/install.sh | sh
This fetches the sct-linux-aarch64 build, which is statically linked against musl.
sct trud cannot resolve DNS
This is the limitation. Every sct trud command fails at the connectivity pre-flight:
Error: Cannot reach NHS TRUD (https://isd.digital.nhs.uk/…).
...
Original error: io: failed to lookup address information: Try again
The network is fine - ping 8.8.8.8 succeeds, and so does curl https://isd.digital.nhs.uk.
Only sct fails, and only on name lookup.
Why. The linux-aarch64 release is a static musl binary, so it carries musl's own DNS
resolver, which reads /etc/resolv.conf. Android has no such file: /etc is a symlink to the
read-only /system/etc, and DNS configuration lives in system properties resolved through the
netd daemon. Bionic's getaddrinfo (used by Termux's own packages, which is why curl and
pkg work) knows how to reach netd; musl's does not. With no nameserver it times out and
returns EAI_AGAIN, which surfaces as "Try again".
ping 8.8.8.8 is not a useful test here - it takes a literal IP address, so no name lookup
happens. To confirm DNS itself is healthy, use a Termux-native binary:
curl -sI https://isd.digital.nhs.uk | head -1 # works: Bionic resolver via netd
Recent versions of sct detect the missing /etc/resolv.conf and say so in the error, pointing
back to this page.
Options
1. Build from source in Termux (confirmed working). Compiling under Termux links against
Bionic, so the resulting binary uses Android's resolver directly and sct trud works,
downloads included:
pkg install rust clang
cargo install sct-rs
This is the heaviest option - rusqlite compiles bundled SQLite, and the Arrow and Parquet
crates are large - so expect a long build and substantial memory use. Confirmed working on a
OnePlus 13 (CPH2653: Snapdragon 8 Elite, 16 GB RAM), including sct trud download.
Performance is better than you might expect: that handset builds a full UK Monolith edition
(837,930 concepts) through NDJSON, SQLite, Parquet, transitive closure, and FST index in about
four and a half minutes, and matches a 22-core laptop on sct fst build. See
Benchmarks.
2. Build the database elsewhere. Only sct trud needs the network, so if you would rather
not compile on a phone, run the download and build on a laptop, copy snomed.db across, and
everything else works with the released binary:
# on a computer
sct trud download --edition uk_monolith --pipeline
# copy snomed.db to the device, then on the phone
sct lookup 22298006
sct ecl "<< 73211009 |Diabetes mellitus|" --db ~/snomed.db
sct tui --db ~/snomed.db
lookup, lexical, ecl, refset, map, codelist, diagram, tui, sayt, mcp, and
serve are all local-only and need no DNS. (sct serve binds a local port, so a phone can
host a FHIR terminology server on your own network, which is a fun if impractical trick.)
3. Run inside a proot distribution. A proot rootfs has a real, writable /etc/resolv.conf,
so even the static binary resolves normally:
pkg install proot-distro
proot-distro install debian
proot-distro login debian
# then install sct inside Debian as usual
Untested by us - reasoned from how proot presents its own root filesystem. If you try it, a report either way is welcome.
Do not byte-patch the binary
A trick circulating for other static musl CLIs on Termux is to edit the /etc/resolv.conf
string inside the binary to point at a writable path. It works, but it invalidates the
release checksum, has to be redone after every upgrade, and leaves you running a binary
that no longer matches what we published. Prefer any of the options above.
Why there is no Android release target
Adding aarch64-linux-android to the release matrix would remove the DNS limitation entirely,
at the cost of an NDK toolchain in CI for the bundled SQLite build. Since cargo install sct-rs
works under Termux and produces exactly such a binary, that cost currently buys convenience
rather than capability, so it is not planned. A native Android app would change the calculation.