Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

Termux Admin & Architecture Guide

Generated June 2026 from termux/termux-app at 30ebb2d

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

This guide documents the internal architecture, build system, configuration surface, security model, and operational concerns of the Termux Android application — the terminal emulator and Linux-environment app published at termux/termux-app. It is written for administrators, ROM/device integrators, plugin developers, contributors, and anyone forking or auditing the codebase.

Important

This repository is the app (UI + terminal emulation + bootstrap installer). The thousands of installable command-line programs are a separate project, termux-packages, which builds the bootstrap archives this app downloads at build time and unpacks at runtime. The two are versioned and maintained independently.


1. Executive Summary

Termux is a native Android application (Java, Android SDK) that provides a full terminal emulator and a self-contained Linux userland under the app's private data directory — no root, no special device configuration. It is organized as a four-module Gradle project:

Module Type Responsibility
terminal-emulator Android library Headless VT100/xterm terminal engine + JNI process/PTY creation. Pure logic, no Android UI.
terminal-view Android library An Android View that renders a terminal session and handles touch, gestures, and text selection. Depends on terminal-emulator.
termux-shared Android library Shared constants, file/permission utilities, settings, shell-command runners, and the local am socket server. Imported by the app and by every plugin.
app Android application The user-facing app: activities, the foreground service, session management, the bootstrap installer, and intent receivers.

The terminal engine and view are deliberately decoupled from Termux specifics so they can be reused (they are published to JitPack as com.termux:terminal-emulator and com.termux:terminal-view). All Termux-specific behavior — paths, package names, intent contracts, properties — is centralized in termux-shared's TermuxConstants, which is the single source of truth for the whole ecosystem.

Key facts at a glance:

Property Value
Package name com.termux
Version versionCode 118, versionName 0.118.0 (latest release 0.118.3)
minSdkVersion 21 (Android 5.0)
targetSdkVersion 28 (Android 9)
compileSdkVersion 36
ndkVersion 29.0.14206865
Android Gradle Plugin 8.13.2
Java level Source/target 1.8 (with core library desugaring)
Bootstrap variant apt-android-7 (default) or apt-android-5
Shared user ID com.termux (shared by app + all plugins)

2. Architecture

2.1 Module dependency graph

                    ┌──────────────────────────┐
                    │          app             │  (com.android.application)
                    │  Activities, Services,   │
                    │  Installer, Receivers    │
                    └───────────┬──────────────┘
                                │ implementation
              ┌─────────────────┼──────────────────┐
              ▼                 ▼                   ▼
   ┌──────────────────┐ ┌──────────────┐  ┌──────────────────┐
   │  terminal-view   │ │ termux-shared│  │  (AndroidX,      │
   │  (Android View)  │ │  (constants, │  │   Material,      │
   └────────┬─────────┘ │  utils, IPC) │  │   Guava, Markwon)│
            │ api       └──────┬───────┘  └──────────────────┘
            ▼                  │ implementation
   ┌──────────────────┐        │
   │ terminal-emulator│◄───────┘
   │  (VT engine+JNI) │
   └──────────────────┘

terminal-view exposes terminal-emulator transitively via api. termux-shared also depends on terminal-view (for terminal constants) and on com.termux:termux-am-library.

2.2 The terminal engine (terminal-emulator)

A headless, reusable terminal emulator written in Java. Principal classes:

Class Role
TerminalEmulator The core state machine: parses the byte stream, implements escape-sequence handling (CSI, OSC, DCS, etc.), cursor and screen state, modes, and styles.
TerminalBuffer The screen + scrollback buffer of TerminalRows.
TerminalRow One row of cells with text and style runs.
TerminalSession Owns a child process and its PTY, pumps bytes between the process and the TerminalEmulator, and notifies a TerminalSessionClient.
KeyHandler Maps Android key events to terminal byte sequences.
TextStyle Packs foreground/background color and attributes into a long.
TerminalColors / TerminalColorScheme 256-color + theme handling.
WcWidth Unicode character-width calculation (wide/CJK/combining).
ByteQueue Thread-safe pipe between the reader thread and the emulator.
JNI Native bridge declarations.

The native side (src/main/jni/termux.c, built with ndk-build via Android.mk) forks the shell, allocates a pseudo-terminal, and wires file descriptors — the mechanism that lets a normal Android app host real subprocesses.

Note

The emulator has the project's strongest test coverage — terminal-emulator/src/test/java/... contains ~19 JUnit test classes covering CSI sequences, DEC private modes, OSC/APC/DCS handling, cursor/screen behavior, resizing, scroll regions, history, and Unicode input. When modifying escape-sequence handling, extend these tests first.

2.3 The terminal view (terminal-view)

Class Role
TerminalView The View subclass that draws a TerminalSession, handles input connection (IME), scrolling, autofill, and the context menu.
TerminalRenderer Canvas drawing of cells, colors, and the cursor.
GestureAndScaleRecognizer Pinch-to-zoom (font size) and scroll gesture handling.
TextSelectionCursorController / TextSelectionHandleView / CursorController Drag-handle text selection UI.
TerminalViewClient Callback interface the host (the app) implements to receive key/scroll/longpress events.

2.4 The shared library (termux-shared)

This is the largest surface and the integration point for plugins. Notable areas:

Package Contents
termux TermuxConstants (all paths, package names, intent contracts), TermuxBootstrap, TermuxUtils.
termux.settings.properties TermuxPropertyConstants (every termux.properties key), TermuxSharedProperties, TermuxAppSharedProperties.
termux.settings.preferences Per-app SharedPreferences wrappers (TermuxAppSharedPreferences, TermuxAPIAppSharedPreferences, …) and TermuxPreferenceConstants.
termux.extrakeys The extra-keys model: ExtraKeysConstants, ExtraKeysInfo, ExtraKeysView, ExtraKeyButton.
shell.command ExecutionCommand (the universal command descriptor), result config/data, and the runner abstraction.
shell.command.runner.app AppShell — runs a background process and captures stdout/stderr/exit code.
shell.command.environment Builds the shell environment ($PREFIX, $HOME, $PATH, $TMPDIR, etc.).
shell.am AmSocketServer — a local socket server that lets in-Termux processes invoke Android's am via the termux-am client (backed by native local-socket.cpp).
file / file.filesystem FileUtils and a partial NIO-style filesystem layer (permissions, attributes, types).
android PermissionUtils, PackageUtils, FeatureFlagUtils, PhantomProcessUtils, ProcessUtils, SELinuxUtils — Android-system integration, including reflection that bypasses hidden-API restrictions.
errors Error, Errno, FunctionErrno — a structured error type used across the codebase instead of bare exceptions.
crash / notification / markdown / logger Crash reporting, notifications, Markwon-based Markdown rendering, and the leveled logger.

2.5 The application (app)

TermuxApplication.onCreate()
  ├─ install crash handler
  ├─ configure logger (log level from prefs)
  ├─ set bootstrap package variant (from BuildConfig.TERMUX_PACKAGE_VARIANT)
  ├─ init TermuxAppSharedProperties (loads termux.properties)
  ├─ init TermuxShellManager
  ├─ set app night mode
  ├─ verify files dir accessible → setup termux-am socket server
  └─ init + write TermuxShellEnvironment to file

TermuxActivity (launcher, singleTask)
  ├─ load properties + theme, inflate terminal layout
  ├─ create TermuxTerminalViewClient + TermuxTerminalSessionActivityClient
  ├─ wire extra-keys toolbar (ViewPager: extra keys ⇄ text input)
  ├─ startService(TermuxService) + bindService(...)
  └─ onServiceConnected:
        if no sessions → TermuxInstaller.setupBootstrapIfNeeded(...) → addNewSession()
        else → restore current/last session

TermuxService (started + bound foreground service)
  ├─ holds the list of TerminalSessions (foreground)
  ├─ holds background AppShell tasks
  ├─ ACTION_SERVICE_EXECUTE → create session or run background command
  ├─ persistent notification (keeps process alive)
  └─ survives TermuxActivity destruction (work keeps running)

RunCommandService (exported, permission-protected)
  └─ ACTION_RUN_COMMAND → validate → forward as ACTION_SERVICE_EXECUTE to TermuxService

Lifecycle highlights:

  • TermuxActivity is a thin UI shell. The TermuxService is the durable owner of sessions and background tasks, so closing the activity does not kill running commands (the notification keeps the process alive).
  • The activity and service communicate through a local ServiceConnection (LocalBinder), not IPC.
  • A BroadcastReceiver inside the activity listens for ACTION_RELOAD_STYLE (re-read properties / restyle), ACTION_NOTIFY_APP_CRASH, and ACTION_REQUEST_PERMISSIONS.

2.6 Bootstrap installation flow (TermuxInstaller)

On first launch (when $PREFIX is missing or empty), the app installs the base system:

  1. Verify the app runs as the primary user and that the files directory is accessible (fail with a clear dialog otherwise).
  2. Show an "Installing…" progress dialog.
  3. Load the bootstrap zip from an embedded native library — System.loadLibrary("termux-bootstrap") then getZip() (JNI). The zip is compiled into the APK at build time (see §4.3).
  4. Extract entries into a staging directory …/files/usr-staging:
    • SYMLINKS.txt entries (format target←linkpath) are collected and recreated as symlinks.
    • Files under bin/, libexec/, and apt helper/method paths get mode 0700.
  5. Atomically rename() staging → $PREFIX (so a crash mid-extract never leaves a half-written prefix).
  6. Write the shell environment file.

On error, a dialog offers Abort or Try again (which wipes $PREFIX and retries). setupStorageSymlinks() (invoked by termux-setup-storage) builds the ~/storage/* symlink tree into Android shared storage.


3. Filesystem & Runtime Layout

All paths derive from TERMUX_PACKAGE_NAME (com.termux) in TermuxConstants. The binaries in the bootstrap have $PREFIX hard-coded at compile time, which is why forking requires rebuilding the bootstrap.

Logical name Path Purpose
App data dir /data/data/com.termux Android private app data
Files dir /data/data/com.termux/files Root of the Termux userland
$PREFIX /data/data/com.termux/files/usr Installed packages root
$PREFIX/bin …/usr/bin Executables
$PREFIX/etc …/usr/etc Package configuration
$PREFIX/lib …/usr/lib Libraries
$PREFIX/libexec …/usr/libexec Helper executables
$PREFIX/share …/usr/share Arch-independent data
$PREFIX/var …/usr/var Variable state (apt, dpkg)
$TMPDIR …/usr/tmp Temp files (auto-cleaned on exit per property)
$HOME /data/data/com.termux/files/home User home directory
Staging prefix …/files/usr-staging Bootstrap extraction staging
Config (primary) ~/.termux/ termux.properties, colors.properties, font.ttf, boot/
Config (secondary) ~/.config/termux/ Alternate termux.properties location
Storage symlinks ~/storage/ Symlinks into Android shared storage

Note

termux.properties is read from the first of ~/.termux/termux.properties then ~/.config/termux/termux.properties. The float plugin uses termux.float.properties in the same two locations.


4. Build System

4.1 Project configuration

Top-level build.gradle pins AGP 8.13.2 and uses mavenCentral(), google(), and jitpack.io repositories. gradle.properties defines the SDK/NDK versions and markwonVersion=4.6.2. The app module applies com.android.application; the three libraries apply com.android.library + maven-publish.

4.2 Package variant

packageVariant = System.getenv("TERMUX_PACKAGE_VARIANT") ?: "apt-android-7"

The variant (apt-android-7 or apt-android-5) selects which bootstrap is bundled and is written into BuildConfig.TERMUX_PACKAGE_VARIANT. TermuxApplication reads it via TermuxBootstrap.setTermuxPackageManagerAndVariant(...). The variant baked into the APK must match the device's Android version — mixing causes startup crashes, which is why the app validates it.

4.3 Bootstrap archives

The downloadBootstraps Gradle task downloads the per-architecture bootstrap zips from termux-packages releases and verifies each against a hard-coded SHA-256:

Variant Source
apt-android-7 bootstrap-2026.02.12-r1+apt.android-7 release (aarch64, arm, i686, x86_64)
apt-android-5 bootstrap-2022.04.28-r6+apt-android-5 release

The download runs as a dependency of javaCompile. The zips are embedded into the APK as a native shared library (app/src/main/cpp/termux-bootstrap.c + termux-bootstrap-zip.S, built with ndk-build) and later read by TermuxInstaller.getZip().

4.4 APK splits, signing, build types

  • ABI splits for x86, x86_64, armeabi-v7a, arm64-v8a plus a universal APK, controlled by TERMUX_SPLIT_APKS_FOR_* env vars. F-Droid ships universal only (it does not support split APKs).
  • Debug builds are signed with the in-repo app/testkey_untrusted.jks (see §6.4).
  • Release builds enable minifyEnabled (ProGuard) with shrinkResources false for reproducible builds.
  • Output APKs are named termux-app_<tag-or-variant>-<buildtype>_<abi>.apk.

4.5 Dependencies

Dependency Version Used for
androidx.core:core 1.13.1 Core compat
androidx.appcompat:appcompat 1.6.1 Themed activities (in termux-shared)
androidx.annotation:annotation 1.9.0 Nullability annotations
androidx.drawerlayout:drawerlayout 1.2.0 Session navigation drawer
androidx.preference:preference 1.2.1 Settings screens
androidx.viewpager:viewpager 1.0.0 Extra-keys ⇄ text-input toolbar
androidx.window:window 1.1.0 Window metrics
com.google.android.material:material 1.12.0 Material UI components
com.google.guava:guava 24.1-jre Collections (ImmutableBiMap), Joiner
io.noties.markwon:* 4.6.2 Markdown rendering (help, reports)
commons-io:commons-io 2.5 File IO (pinned ≤2.5 to keep java.nio.file.Path-free for Android < 8)
org.lsposed.hiddenapibypass:hiddenapibypass 6.1 Bypass hidden-API restrictions via reflection
com.termux:termux-am-library v2.0.0 am command bridge
junit:junit / org.robolectric:robolectric 4.13.2 / 4.10 Unit tests
com.android.tools:desugar_jdk_libs 1.1.5 Core library desugaring

Warning

commons-io is intentionally held at 2.5. Newer versions reference java.nio.file.Path, which is missing on Android < 8 and causes runtime NoClassDefFoundError. Do not bump it without dropping Android 5/6 support.


5. Android Components Reference

All components are declared in app/src/main/AndroidManifest.xml. The ${TERMUX_PACKAGE_NAME} placeholder resolves to com.termux.

Component Type Exported Notes
.app.TermuxActivity Activity ✅ Launcher (MAIN/LAUNCHER, LEANBACK_LAUNCHER), singleTask, declares app shortcuts
.HomeActivity (alias) Activity-alias ✅ IOT_LAUNCHER — auto-launch on boot for Android Things
.app.activities.HelpActivity Activity ❌ In-app wiki viewer
.app.activities.SettingsActivity Activity ✅ Settings root
.shared.activities.ReportActivity Activity ❌¹ Markdown report/crash viewer
.app.api.file.FileReceiverActivity Activity ❌ Internal file-receive handler (noHistory, own task affinity)
.app.api.file.FileShareReceiverActivity (alias) Activity-alias ✅ Handles SEND for most MIME types
.app.api.file.FileViewReceiverActivity (alias) Activity-alias ✅ Handles VIEW for most MIME types
.filepicker.TermuxDocumentsProvider Provider ✅ com.termux.documents authority; MANAGE_DOCUMENTS-protected
.app.TermuxOpenReceiver$ContentProvider Provider ✅ com.termux.files authority; RUN_COMMAND-permission protected
.app.TermuxOpenReceiver Receiver ❌ Backs the termux-open utility
.app.event.SystemEventReceiver Receiver ❌ BOOT_COMPLETED
.shared.activities.ReportActivity$ReportActivityBroadcastReceiver Receiver ❌ Report actions
.app.TermuxService Service ❌ Session/background-task owner; foreground service
.app.RunCommandService Service ✅ ACTION_RUN_COMMAND; RUN_COMMAND-permission protected

¹ ReportActivity is launched internally (documentLaunchMode=intoExisting).


6. Security Analysis

6.1 Threat model overview

Termux executes arbitrary user code by design, so its security boundary is what other apps and the system can do to Termux, and what Termux exposes to other apps. The main controls are the shared-user-ID signature requirement, the RUN_COMMAND permission, and the allow-external-apps opt-in.

6.2 Shared user ID & signature enforcement

The app and all plugins declare android:sharedUserId="com.termux". Android only co-locates apps under a shared UID if they are signed with the same key. This is what allows plugins to read Termux's files and properties — and why all APKs must come from one source. It also means a malicious APK cannot join the com.termux UID without the signing key.

6.3 The RUN_COMMAND surface

custom permission:  com.termux.permission.RUN_COMMAND   (protectionLevel: dangerous)
guarded service:    .app.RunCommandService  (exported, permission-protected)
guarded provider:   .app.TermuxOpenReceiver$ContentProvider (com.termux.files)
runtime gate:       allow-external-apps = true   (in termux.properties; default false)

Two independent checks must both pass for an external app to run a command:

  1. The caller holds com.termux.permission.RUN_COMMAND (a dangerous permission, surfaced to the user).
  2. allow-external-apps is true in termux.properties.

RunCommandService additionally validates that the executable exists, is a regular file, and is readable/executable, canonicalizes paths, and validates working directories before forwarding to TermuxService. If allow-external-apps is violated, it force-shows a notification so the user is alerted that an app attempted to run a command — defending against a malicious or imported automation project acting without consent.

Caution

allow-external-apps is a security property. TermuxConstants documents that it should only be modified from a properties file the user controls, and the path list is fixed so plugins cannot redirect it. Treat enabling it as granting code-execution to any app holding the RUN_COMMAND permission.

6.4 The public test key

GitHub debug builds and the in-repo app/testkey_untrusted.jks use a publicly shared key (Owner CN=APK Signer, SHA-256 B6:DA:01:48:…:E5:E1). Anyone can build an "update" that installs over a GitHub build. The known release signing-certificate digests are encoded in TermuxConstants:

Channel SHA-256 digest (cert)
F-Droid 228FB2CFE90831C1499EC3CCAF61E96E8E1CE70766B9474672CE427334D41C42
GitHub B6DA01480EEFD5FBF2CD3771B8D1021EC791304BDD6C4BF41D3FAABAD48EE5E1
Google Play Store 738F0A30A04D3C8A1BE304AF18D0779BCF3EA88FB60808F657A3521861C2EBF9
Termux Devs F7A038EB551F1BE8FDF388686B784ABAB4552A5D82DF423E3D8F1B5CBE1C69AE

Caution

Only trust GitHub APKs downloaded directly from the official repository. Builds distributed elsewhere may be forged with the public test key.

6.5 Requested permissions

Permission Why Termux requests it
INTERNET, ACCESS_NETWORK_STATE Networking for installed programs
READ/WRITE_EXTERNAL_STORAGE, MANAGE_EXTERNAL_STORAGE termux-setup-storage; broad storage access on modern Android
FOREGROUND_SERVICE Keep sessions alive via the persistent-notification service
WAKE_LOCK termux-wake-lock for long-running tasks
VIBRATE Terminal bell (vibrate mode)
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS Prompt the user to whitelist Termux from battery optimization
SYSTEM_ALERT_WINDOW Display-over-other-apps (used by Termux:Float)
RECEIVE_BOOT_COMPLETED Boot scripts (Termux:Boot)
REQUEST_INSTALL_PACKAGES Install APKs from the terminal
READ_LOGS, DUMP, WRITE_SECURE_SETTINGS, PACKAGE_USAGE_STATS Diagnostics and mitigating phantom-process killing on Android 12+ (several are only grantable via ADB)
SET_ALARM Scheduling helpers
com.termux.permission.RUN_COMMAND (custom) Gate external command execution

6.6 Hidden-API usage

termux-shared uses hiddenapibypass and reflection (ReflectionUtils, FeatureFlagUtils, PhantomProcessUtils) to read framework internals such as Android feature flags — needed to detect and help mitigate phantom-process killing. This is fragile across Android versions and OEM builds; treat reflection-backed paths as best-effort with graceful fallback (the code already returns UNKNOWN/null on failure).

6.7 Historical vulnerability

Versions before 0.118.0 had a world-readable vulnerability (disclosure). Users should run 0.118.0 or later. This is fixed in the documented codebase; it is noted here for audit history.


7. Configuration Mastery: Full termux.properties Reference

Loaded from ~/.termux/termux.properties (or ~/.config/termux/termux.properties). Defined in TermuxPropertyConstants. Reload at runtime via the ACTION_RELOAD_STYLE broadcast (triggered by the Style menu action).

7.1 Boolean properties

Key Default Effect
allow-external-apps false Permit external apps to run commands via RUN_COMMAND
disable-file-share-receiver false Remove Termux from the Android Share menu
disable-file-view-receiver false Remove Termux from the Open with menu
disable-hardware-keyboard-shortcuts false Disable all hardware-keyboard session shortcuts
disable-terminal-session-change-toast false Suppress the session-switch toast
enforce-char-based-input false Char-based IME workaround (Samsung et al.)
extra-keys-text-all-caps true Uppercase extra-key labels
hide-soft-keyboard-on-startup false Start with keyboard hidden
run-termux-am-socket-server true Run the local am socket server at startup
terminal-onclick-url-open false Open URLs on single tap
ctrl-space-workaround false Fix Ctrl+Space on some ROMs
fullscreen false Fullscreen terminal
use-fullscreen-workaround false Fullscreen layout workaround
use-black-ui (deprecated) Legacy black UI toggle

7.2 Integer / float properties (with valid ranges)

Key Range Default Effect
bell-character vibrate / beep / ignore vibrate Bell behavior
terminal-cursor-blink-rate 0 or engine min–max 0 Blink interval (ms); 0 = no blink
terminal-cursor-style block / underline / bar block Cursor shape
terminal-margin-horizontal 0–100 3 Left/right margin (dp)
terminal-margin-vertical 0–100 0 Top/bottom margin (dp)
terminal-transcript-rows engine min–max engine default Scrollback rows
terminal-toolbar-height 0.4–3 1 Extra-keys toolbar height scale
delete-tmpdir-files-older-than-x-days-on-exit -1–100000 3 Clean $TMPDIR on exit (-1 none, 0 all)

7.3 String / behavior properties

Key Values Default Effect
back-key back / escape back Back button behavior
volume-keys virtual / volume virtual Volume-Down as modifier vs. normal volume
soft-keyboard-toggle-behaviour show/hide / enable/disable show/hide Keyboard-toggle action
night-mode true / false / system system Theme
default-working-directory absolute path $HOME New-session CWD
extra-keys matrix (see UG) two-row default Extra-keys layout
extra-keys-style default, arrows-only, … default Key glyph style

7.4 Session shortcut properties

Key Action
shortcut.create-session New session
shortcut.next-session Next session
shortcut.previous-session Previous session
shortcut.rename-session Rename session

8. Intent API Reference

8.1 RUN_COMMAND (public, plugin-facing)

Target: service com.termux/.app.RunCommandService, action com.termux.RUN_COMMAND. Requires the RUN_COMMAND permission and allow-external-apps = true.

Extra Type Meaning
com.termux.RUN_COMMAND_PATH String Absolute executable path (required)
com.termux.RUN_COMMAND_ARGUMENTS String[] Arguments
com.termux.RUN_COMMAND_STDIN String Standard input
com.termux.RUN_COMMAND_WORKDIR String Working directory
com.termux.RUN_COMMAND_BACKGROUND boolean Background (app-shell) vs. foreground (terminal-session)
com.termux.RUN_COMMAND_RUNNER String Explicit runner (terminal-session / app-shell); overrides BACKGROUND
com.termux.RUN_COMMAND_SESSION_ACTION String Session/activity action for foreground commands
com.termux.RUN_COMMAND_COMMAND_LABEL / _DESCRIPTION / _HELP String Metadata for notifications/reports
com.termux.RUN_COMMAND_BACKGROUND_CUSTOM_LOG_LEVEL String Per-command log level for background runs
…RUN_COMMAND_REPLACE_COMMA_ALTERNATIVE_CHARS_IN_ARGUMENTS / …_COMMA_ALTERNATIVE_CHARS_IN_ARGUMENTS boolean / String Comma-escaping for am-delivered arguments
…RUN_COMMAND_PENDING_INTENT Parcelable Pending intent to receive results
…RUN_COMMAND_RESULT_DIRECTORY (+ _SINGLE_FILE, _FILE_BASENAME, _FILE_OUTPUT_FORMAT, _FILE_ERROR_FORMAT, _FILES_SUFFIX) String/boolean Write results to files

Reference: RUN_COMMAND Intent wiki.

8.2 TERMUX_SERVICE (internal execution contract)

RunCommandService forwards validated commands to TermuxService as action com.termux.service_execute with a com.termux.file-scheme URI and com.termux.execute.* extras (arguments, workdir, background, runner, session_action, result extras). The session_action integer selects whether to open/switch the session and whether to bring the activity forward.

8.3 TERMUX_ACTIVITY broadcasts

Action Effect
com.termux.app.reload_style Re-read termux.properties and restyle (optionally recreate the activity)
(crash-notify action) Show a crash notification from the crash-log file
(request-permissions action) Trigger the storage-permission request flow

9. Operations

Termux has no server-side deployment — it is a client app installed on devices. "Operations" here means device-side lifecycle and fleet/integration management.

9.1 Install / update / rollback

# Install or update (single source!)
adb install -r termux-app_apt-android-7-release_universal.apk
Performing Streamed Install
Success
  • Updates are normal APK updates from the chosen source. F-Droid lags GitHub by days.
  • Rollback requires uninstalling (data is not downgrade-compatible across major changes); back up first.

9.2 Keeping Termux alive (Android 12+)

The single biggest operational issue is the OS killing background processes. Mitigations, in order of effectiveness:

  • [ ] Disable battery optimization for Termux (Android Settings → Apps → Termux → Battery).
  • [ ] Acquire a wake-lock for long jobs (termux-wake-lock or context-menu Keep screen on).
  • [ ] Disable phantom-process and excessive-CPU killing (ADB / Developer Options; see issue #2366).
  • [ ] Keep critical work in the foreground session.

9.3 Logging & diagnostics

  • Set log level: Settings → Termux → Debugging → Log Level (Off/Normal/Debug/Verbose).
  • Capture logs from the device: logcat -d > logcat.txt, or over ADB from a PC.
  • Generate a full report: context menu → More → Report Issue.

Warning

Verbose logging may write private data to logcat and slows execution. Revert to Normal after debugging. Set log level for both the plugin and the main app when diagnosing plugin issues.

9.4 Backups

Back up ~/ (home) and $PREFIX before uninstalling or switching sources. See Backing up Termux.


10. Forking & Repackaging

TermuxConstants is the canonical place to change identity. To fork under a new package name you must change, at minimum:

  • TERMUX_PACKAGE_NAME in TermuxConstants.
  • applicationId and the manifestPlaceholders (TERMUX_PACKAGE_NAME, *_APP_NAME) in app/build.gradle.
  • The ENTITY values in strings.xml of termux-app and termux-shared.
  • shortcut.xml and *_preferences.xml (dynamic variables are not supported there).
  • Rebuild the bootstrap archives for the new $PREFIX (binaries hard-code the prefix path) — see Building packages.

Important

Not all plugins use TermuxConstants; some still hard-code com.termux and must be patched manually when forking. Contributions must reference shared constants from termux-shared rather than hard-coding paths — PRs with hard-coded values are rejected.


11. Code Quality & Conventions

  • Centralized constants — every path, package name, intent action, and extra lives in TermuxConstants/TermuxPropertyConstants with a versioned changelog header. This eliminates hard-coded strings across the app and plugins.
  • Structured errors — the Error/Errno types carry a code, type, message, and throwable list, and render to log/Markdown form, instead of throwing bare exceptions.
  • Bidirectional value maps — properties with enumerated values use Guava ImmutableBiMap to map user-facing strings to internal int/string values (and back).
  • Reusable engine/view — terminal-emulator and terminal-view are kept free of Termux specifics and published independently to JitPack.
  • Conventional Commits — commit messages must follow Conventional Commits with capitalized types (Added, Changed, Deprecated, Removed, Fixed, Security) so changelogs are generated automatically. versionName must be valid SemVer 2.0.0 (validated in build.gradle).

Testing strategy

  • terminal-emulator has thorough JUnit coverage of the emulator (CSI/OSC/DCS, modes, cursor, resize, history, Unicode).
  • The app uses Robolectric for unit tests (TermuxActivityTest, FileReceiverActivityTest).
  • termux-shared includes instrumented tests (ExampleInstrumentedTest) and a FileUtilsTests harness.

Note

Test density is highest in the engine and thinnest in the app/UI layer — appropriate, since the engine encodes the most complex, regression-prone logic. New escape-sequence or buffer behavior should always land with tests.


12. Potential Improvements

Observations from the source, for maintainers and contributors:

  • Android 12+ phantom-process killing remains the dominant stability complaint (issues #5032, #5086, #3059). The app already detects feature flags via reflection; a guided in-app mitigation wizard (where permissions allow) would cut support load.
  • targetSdkVersion 28 is well behind the platform. Raising it unlocks modern APIs but collides with the legacy-storage and exec-from-data-dir behaviors Termux depends on; any bump needs careful validation against scoped storage and W^X exec restrictions.
  • commons-io pinned at 2.5 for Android <8 compatibility — revisit if/when the minimum SDK rises.
  • Paste-of-control-characters crash (#5119) is a robustness gap in input sanitization worth hardening in TerminalView/KeyHandler.
  • Hidden-API reflection is inherently brittle across OEM ROMs; continue to guard every reflective call with the existing UNKNOWN/null fallbacks and log clearly when the platform shape changes.
  • Maintainer capacity — the README explicitly calls for app maintainers; triage automation around the high-volume, low-signal issue tracker would help.

13. Quick Reference

Key paths

Item Path
$PREFIX /data/data/com.termux/files/usr
$HOME /data/data/com.termux/files/home
$TMPDIR /data/data/com.termux/files/usr/tmp
Properties ~/.termux/termux.properties
Storage links ~/storage/

Build commands

./gradlew assembleDebug      # build debug APKs (signed with the public test key)
./gradlew assembleRelease    # build release APKs (minified)
./gradlew test               # run unit tests
./gradlew :app:versionName   # print the version name

Key constants (in termux-shared)

Constant class Defines
TermuxConstants Package names, paths, intent actions & extras, signing digests, URLs
TermuxPropertyConstants Every termux.properties key, default, and value map
TermuxPreferenceConstants SharedPreferences keys
ExtraKeysConstants Extra-key names, aliases, and display glyph maps

Plugin packages

Plugin Package
Termux:API com.termux.api
Termux:Boot com.termux.boot
Termux:Float com.termux.window
Termux:Styling com.termux.styling
Termux:Tasker com.termux.tasker
Termux:Widget com.termux.widget