An SSH client for Android
Built because every mobile SSH client makes you choose between convenient and trustworthy,
and that's a stupid choice.
Requires Android 12 (API 31) or later. GPLv3.
Unfolded, the session list and the terminal share the screen; collapsing the split gives the terminal the full width.
- Dropped connections reconnect on their own, without re-prompting for a password; optional
tmux-backed sessions reattach with scrollback intact. - Host key verification on first connect, with the fingerprint shown. A changed key blocks the connection; there is no accept-all mode, and a background run never answers a prompt for you.
- Credentials encrypted with the Android Keystore, hardware-backed where available, with an optional biometric unlock per credential.
- Key enrolment: generate a key, install it in the host's
authorized_keys, replace the saved credential. The private key never leaves the device. - Password, private key (imported or generated on device), and keyboard-interactive auth.
- Local and remote port forwarding, SOCKS5, ProxyJump chaining,
~/.ssh/configimport. - Saved scripts, run from the app, a widget, an app shortcut, a Quick Settings tile, or another app.
- SFTP upload and download.
- Per-host terminal profile, colour scheme and key bar layout, each overriding a global default.
- 256-colour and truecolour output, wide characters, alternate screen.
- No analytics, no telemetry, no crash reporting. It talks to the hosts you give it, and nothing else.
Every release ships a signed APK, built by GitHub Actions from the tag - an unsigned build never reaches the release page:
Note
Forwarded ports and the SOCKS5 proxy bind to loopback unless you say otherwise. Binding wider is a choice you have to make on purpose, which is rather the point. The coffee shop Wi-Fi does not need a route into your homelab.
Two product flavours, identical but for one dependency:
./gradlew assembleFossRelease # no proprietary dependencies - the F-Droid build
./gradlew assemblePlayRelease # adds Play Billing, for the optional one-time tip
SupporterBilling is an interface in :app's main source set with one implementation per
flavour, so only play links com.android.billingclient.
On foss the Support section of Settings does not exist.
Debug builds, unit tests and lint:
./gradlew assembleFossDebug
./gradlew testFossDebugUnitTest
./gradlew lintFossDebug
The Room migration and Keystore tests are instrumented, so they want a real device or emulator - which is to say the two things you least want quietly broken are the two that take the most effort to check.
Writing a VT parser from scratch is a fine way to lose a year, so this one is borrowed.
:terminal-core contains twelve files from termux-app's terminal-emulator module, ten of them
byte-identical to upstream. TerminalRenderer.kt in :app is a Kotlin port of upstream's
TerminalRenderer.java. The package is left as com.termux.terminal so the vendored files stay a
mergeable diff.
terminal-core/VENDORING.md records the upstream commit, the file list and the edits made. The
engine's pty/JNI subprocess code is not used; sessions are remote shells over SSH.
Third-party attribution lives in NOTICE, which a Gradle task copies into res/raw for the in-app
licence screen.
GPLv3 - see LICENSE. The vendored terminal engine is GPLv3 from termux-app; NOTICE has the
details.





