- Java 51.6%
- Kotlin 37.1%
- Rust 11.3%
aapt on the released RTerm-1.3.0.apk shows android:debuggable=true and versionCode 9 / versionName 1.2.2 — it contains the 1.3.0 code but was built before the version bump, so Android displays it as 1.2.2 and won't treat it as an upgrade over a real 1.2.2 install. debuggable=true also lets anyone with ADB access to an unlocked device run-as the app or attach a debugger, reaching secrets after decryption. Document both instead of letting the README imply a release build. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AjjikhyF7Zy86f3W6dX2kf |
||
|---|---|---|
| rterm | ||
| .gitignore | ||
| ARCHITECTURE.md | ||
| PLAN-v1.1.md | ||
| README.md | ||
| ROADMAP.md | ||
| SECURITY-REVIEW-Rin.md | ||
| SECURITY-REVIEW-Termux.md | ||
| STATUS.md | ||
RTerm — a fast, SSH-first Android terminal
RTerm is a lean, SSH-only Android terminal built around a Rust core. It exists to fix the exact things that make SSH-over-Termux painful: no real SHIFT key, key combos that don't encode correctly, a renderer that chokes on vim/tmux, and sessions that die the moment you switch apps.
⬇️ Download
RTerm-1.3.0.apk — ~12.3 MB · arm64-v8a · Android 7.0+
Sideload only, no Play Store. All releases: Releases · install steps
![]() |
![]() |
| Live SSH session — full VT100 grid | Configurable key bar with sticky modifiers |
Why RTerm
Termux is great — but for SSH it gets in the way. RTerm is SSH-only and fixes the friction.
| What you get | |
|---|---|
| ⌨️ | Modifier keys that work — a real SHIFT key (Termux/Rin have none). Sticky one-shot & lock modifiers. Shift+Tab actually sends ESC [ Z; Ctrl/Alt combos encoded correctly in the Rust core. |
| 🖥️ | Full-screen apps — a real VT100 grid (vendored Termux engine) so vim, tmux, htop and ANSI colors render properly, not a line-buffer that strips escape codes. |
| ⚡ | Low latency — TCP_NODELAY, keys firing on finger-down, protocol keepalives that hold NAT paths open. Tuned for sub-second echo. |
| 🗂️ | Multi-session tabs — several SSH sessions at once, each with its own identity color and sticky modifiers. |
| 🔁 | Stays alive & reconnects — a foreground service (with notification) keeps the session alive when you leave the app; auto-reconnect with backoff plus a manual retry button. |
| 🔐 | Host-key pinning — trust-on-first-use with a hard-fail on mismatch (MITM protection). |
| 📁 | SFTP file browser — browse remote dirs, tap to download, upload from the phone, via Android's Storage Access Framework (no storage permission). |
| 🔀 | Port forwarding — -L local forwards and a SOCKS5 dynamic proxy over the SSH channel. Tunnel to your server's internal services from the phone browser. |
| 🤖 | Macros & automation — script routines (send / wait / wait-for-output / if-contains-goto / copy), auto-run on connect, and daily scheduled headless runs. |
| 🎛️ | Configurable key bar — add/remove keys & rows, long-press symbol popups, hide/show from the ▶ menu, and native sequence keys like ctrl+b q (tmux prefix). |
| 🎨 | Themes & fonts — 8 color schemes (Dracula, Solarized, Gruvbox, Nord, …), bundled monospace fonts, your own uploaded fonts, and a zoom dialog — all applied live. |
| 📦 | Config backup — export connections, macros, key bar & forwards. Secrets stripped by default; opt-in passphrase encryption (PBKDF2 → AES-256-GCM). |
Security & privacy
A terminal app handles your most sensitive credentials. RTerm is built to respect that.
- Minimal permissions. Only
INTERNETplus foreground-service / notification / boot. No storage, contacts, location, camera or microphone. - Secrets encrypted at rest. Passwords, inline keys & passphrases are wrapped with AES-256-GCM under a hardware-backed Android Keystore key that never leaves the device.
- Host-key verification. First contact pins the fingerprint; any later mismatch hard-fails the connection.
- Backups disabled.
android:allowBackup="false"— app data can't be pulled viaadb backup. - Tight component surface. All services & receivers are non-exported; the Quick-Settings tile is system-protected (
BIND_QUICK_SETTINGS_TILE). - On-device keys never leave. SSH keys generated in the app are excluded from config export.
- Open source. The complete source is in this repository — audit it yourself.
These properties describe the source. The currently published APK is a debug build, which relaxes the on-device protections — see the install warning.
Install
- Download
RTerm-1.3.0.apk. - Copy it to your phone (or
adb install RTerm-1.3.0.apk). - On the phone: Settings → Apps → Special access → Install unknown apps, allow your file manager / browser to install.
- Tap the APK to install, then open RTerm.
- Add a connection (host / port / user + password or key), connect, and try SHIFT then TAB.
Verify your download with sha256sum RTerm-1.3.0.apk:
50a9bbfca1176ca110a7914b74bd6d8c0df92e1cdcb3c9809c42522e2b2ace16 RTerm-1.3.0.apk
Warning
The current release artifact is a debug build. Two consequences worth knowing before you put real credentials in it:
- It is signed with a local debug key, so Android warns it's from an "unknown developer", and it carries
android:debuggable="true". On a debuggable app anyone with USB/ADB access to the unlocked device canrun-asthe app to read its private data directory, or attach a debugger to the running process — which reaches secrets after they've been decrypted. The at-rest encryption below still holds; this weakens the on-device threat model.- It reports
versionCode 9 / 1.2.2internally (it was built before the version bump), even though it contains the 1.3.0 code. Android will display it as 1.2.2 and will not treat it as an upgrade over a real 1.2.2 install.A release-signed, non-debuggable, correctly-versioned build will replace it. Until then, prefer building from source if either point matters to you.
Specifications
| Version | 1.3.0 (source: versionCode 10 — see the build note above) |
| Application ID | ovh.binary.rterm |
| Min / target Android | 7.0 (API 24) / 14 (API 34) |
| Architecture | arm64-v8a (modern phones) |
| APK size | ~12.3 MB |
| SSH engine | russh (Rust) |
| Terminal engine | vendored Termux (Apache-2.0) |
| UI | Kotlin + Jetpack Compose |
Build from source
Prerequisites: JDK 17+, Rust + cargo-ndk, Android SDK
(platform 34, build-tools 34), NDK r26.
# 1. Rust native library (arm64 .so)
cd rterm
export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/26.3.11579264
cargo ndk -t arm64-v8a -o android/app/src/main/jniLibs \
build -p rterm-core --release --features android
# 2. APK
cd android
echo "sdk.dir=$ANDROID_HOME" > local.properties
./gradlew :app:assembleDebug
# -> app/build/outputs/apk/debug/app-debug.apk
# 3. (optional) Rust test suite
cd .. && cargo test --workspace
Architecture
The SSH transport is Rust (russh), running on a background thread with its own tokio runtime.
Terminal rendering & input use the Termux engine (vendored, Apache-2.0). RTerm supplies the
keyboard bar, credential/connection/macro storage, the foreground service, and the Compose UI shell.
rterm/
├── core/ rterm-core (Rust): JNI bridge — key encoder + SSH JNI → librterm_core.so
├── ssh/ rterm-ssh (Rust): SshSession over russh; forward + sftp modules; loopback tests
└── android/ Kotlin + Jetpack Compose app
├── terminal-emulator/ vendored Termux engine (Apache-2.0)
├── terminal-view/ vendored Termux view (Apache-2.0)
└── app/ RTerm app — UI, storage, foreground service, macros
More detail: ARCHITECTURE.md · ROADMAP.md ·
STATUS.md · upstream reviews in
SECURITY-REVIEW-Rin.md and
SECURITY-REVIEW-Termux.md.
License
The vendored Termux terminal engine (rterm/android/terminal-emulator,
rterm/android/terminal-view) is Apache-2.0 — see the NOTICE.md in each module. RTerm's own
application source is published here as-is.
Built and published from source on a self-hosted Forgejo instance.

