World's first Standalone Termux SDK for Android.
Embed a full Linux environment inside any Android app β no Termux installation required.
libtermux-android is a high-performance Android library that bootstraps a complete, isolated Linux environment (Termux runtime) inside your app's private storage. Your users get all the power of a Linux terminal without ever knowing it exists.
Your App β LibTermux SDK β Isolated Linux Env β bash, python, node, ruby, pkg install...
| Feature | Description |
|---|---|
| Standalone Mode | No Termux app required β bootstrap is auto-installed |
| Kotlin DSL API | Clean, idiomatic Kotlin interface |
| Java Compatible | Full Java Builder pattern support |
| Multi-language | Python Β· Node.js Β· Bash Β· Ruby Β· Perl + any pkg |
| Package Manager | pkg install, pip install, npm install -g |
| Streaming Output | Real-time Flow<OutputLine> from running processes |
| Background Service | Keep scripts running when app is minimized |
| TerminalView | Drop-in terminal UI widget |
| JNI PTY Layer | Full pseudo-terminal support for interactive programs |
| Multi-arch | arm64-v8a Β· x86_64 Β· armeabi-v7a Β· x86 |
// settings.gradle.kts
repositories {
maven { url = uri("https://jitpack.io") }
}
// app/build.gradle.kts
dependencies {
implementation("com.github.libtermux:libtermux-android:1.0.0")
// Optional: terminal UI widget
implementation("com.github.libtermux:terminal-view:1.0.0")
}<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<dependency>
<groupId>com.github.libtermux</groupId>
<artifactId>libtermux-android</artifactId>
<version>1.0.0</version>
</dependency>class MyActivity : AppCompatActivity() {
private val termux by lazy {
LibTermux.create(this) {
autoInstall = true
logLevel = LogLevel.DEBUG
env("MY_APP", "libtermux")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleScope.launch {
// 1. Initialize (downloads bootstrap on first run ~30MB)
termux.initialize().collect { state ->
when (state) {
is InstallState.Downloading -> showProgress(state.progress)
is InstallState.Completed -> onReady()
is InstallState.Failed -> showError(state.error)
else -> {}
}
}
}
}
private suspend fun onReady() {
val bridge = termux.bridge
// Run any shell command
val result = bridge.run("uname -a")
println(result.stdout)
// Run Python
val py = bridge.python("""
import json, sys
print(json.dumps({"python": sys.version, "status": "works!"}))
""")
println(py.stdout)
// Install packages
bridge.install("git", "curl", "wget")
// Stream real-time output
bridge.runStreaming("ping -c 5 8.8.8.8").collect { line ->
when (line) {
is OutputLine.Stdout -> updateUI(line.text)
is OutputLine.Stderr -> showError(line.text)
is OutputLine.Exit -> println("done: ${line.code}")
}
}
}
}LibTermux termux = LibTermux.builder(this)
.autoInstall(true)
.logLevel(LogLevel.DEBUG)
.build();
// Blocking init (run on background thread!)
new Thread(() -> {
try {
termux.initializeBlocking();
String output = termux.getBridge().runOrThrow("echo Hello Linux!");
Log.d("TAG", output); // Hello Linux!
} catch (Exception e) {
Log.e("TAG", "Failed", e);
}
}).start();// Start background service
TermuxBackgroundService.start(context, config)
// Run a long-running server in background
TermuxBackgroundService.runCommand(context, "node-server", "node server.js")<!-- activity_main.xml -->
<com.libtermux.view.TerminalView
android:id="@+id/terminal"
android:layout_width="match_parent"
android:layout_height="match_parent" />val session = termux.sessions.createSession("main")
binding.terminal.attachSession(session)
session.run("bash") // Start interactive shellval session1 = termux.sessions.createSession("python-repl")
val session2 = termux.sessions.createSession("node-server")
session1.run("python3 myapp.py")
session2.run("node server.js")
termux.sessions.closeSession(session1.session.id)// Install packages
termux.packages.install("python", "nodejs", "git", "curl")
termux.packages.pipInstall("requests", "numpy", "flask")
termux.packages.npmInstall("express", "axios")
// Search
val results = termux.packages.search("machine learning")
// List installed
val installed = termux.packages.listInstalled()// Write a Python script to HOME
termux.bridge.writeFile("app.py", """
import flask
app = flask.Flask(__name__)
@app.route('/')
def hello(): return "Hello from LibTermux!"
app.run(host='127.0.0.1', port=8080)
""")
// Run it
termux.bridge.run("python3 ~/app.py")
// Read output
val content = termux.bridge.readFile("output.txt")libtermux-android optionally integrates with Shizuku to run commands with elevated (root/system) privileges. This allows your app to perform system-level operations like accessing protected files, modifying system settings, or executing privileged commandsβall without requiring the user to manually install Shizuku or root their device (Shizuku can run via ADB or root).
The library provides a simple API that falls back to normal execution when Shizuku is unavailable, so your app remains functional in all environments.
Add the Shizuku module dependency:
dependencies {
implementation("com.github.libtermux:libtermux-android:1.0.0")
implementation("com.github.libtermux:shizuku:1.0.0") // optional: elevated commands
}class MyActivity : AppCompatActivity() {
private lateinit var shizukuTermux: ShizukuTermux
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
shizukuTermux = ShizukuTermux.getInstance(this) {
autoInstall = true
}
lifecycleScope.launch {
shizukuTermux.initialize().collect { state ->
if (state is InstallState.Completed) {
// Request Shizuku permission if needed
if (!shizukuTermux.isShizukuPermissionGranted) {
shizukuTermux.requestShizukuPermission()
}
// Run normal command
val normal = shizukuTermux.bridge.run("echo Hello")
println(normal.stdout)
// Run elevated command (e.g., read system files)
val elevated = shizukuTermux.runElevated("cat /system/build.prop")
println("Exit code: ${elevated.exitCode}")
}
}
}
}
}Add the following permission to your AndroidManifest.xml:
<uses-permission android:name="dev.rikka.shizuku.permission.API_V23" />Optionally, include the Shizuku provider for automatic service binding:
<provider
android:name="rikka.shizuku.ShizukuProvider"
android:authorities="${applicationId}.shizuku"
android:enabled="true"
android:exported="false" />Method Description
ShizukuTermux.getInstance(context, config) Get singleton instance (also supports DSL). isShizukuAvailable Check if Shizuku service is installed and running. isShizukuPermissionGranted Check if permission has been granted. suspend fun requestShizukuPermission() Request permission (suspends until granted/denied). suspend fun runElevated(command, env, workDir) Execute command with elevated privileges. Returns ElevatedResult.
If Shizuku is not installed, not running, or permission is denied, runElevated() automatically falls back to normal execution within the Termux environment. You can check the elevated flag in the result to know how it was executed.
libtermux-android/
βββ core/ # Main SDK library
β βββ src/main/
β βββ kotlin/com/libtermux/
β β βββ LibTermux.kt # β Main entry point
β β βββ TermuxConfig.kt # β Configuration DSL
β β βββ bootstrap/ # Bootstrap installer
β β βββ executor/ # Command execution engine
β β βββ fs/ # Virtual file system
β β βββ pkg/ # Package manager
β β βββ bridge/ # Developer API bridge
β β βββ service/ # Background service
β β βββ utils/ # Utilities + JNI bindings
β βββ jni/ # C++ native layer (PTY, process, symlinks)
β
βββ terminal-view/ # Terminal UI widget (optional)
β βββ src/main/kotlin/
β βββ com/libtermux/view/
β βββ TerminalView.kt
β
βββ shizuku/ # Shizuku integration for elevated commands (optional)
β βββ src/main/kotlin/
β βββ com/libtermux/shizuku/
β βββ ShizukuTermux.kt # Entry point for elevated execution
β βββ ElevatedResult.kt # Result class for elevated commands
β
βββ sample/ # Demo app
β βββ src/main/kotlin/
β βββ com/libtermux/sample/
β βββ MainActivity.kt
β βββ MainViewModel.kt
β
βββ scripts/
β βββ setup_dev.sh # Developer environment setup
β βββ publish_local.sh # Publish to local Maven
β
βββ .github/workflows/
βββ ci.yml # CI: lint + test + build
βββ release.yml # Release: publish to Maven Central
Add to your AndroidManifest.xml:
<!-- Required for bootstrap download -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Required for background service -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<!-- Optional: for notifications -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Your Android App β
β β
β LibTermux.create(context) { ... } β
β β β
β ββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββ β
β β LibTermux (Singleton) β β
β β βββββββββββββββ ββββββββββββββββ βββββββββββββ β β
β β βTermuxBridge β βSessionManagerβ βPackageMgr β β β
β β ββββββββ¬βββββββ ββββββββ¬ββββββββ βββββββ¬ββββββ β β
β β βββββββββββββββββ¬β β β β
β β ββββββββΌβββββββ β β β
β β βCommandExec βββββββββββββ β β
β β ββββββββ¬βββββββ β β
β β ββββββββββββββββββββββ β ββββββββββββββββββββββββ β β
β β βVirtualFileSystem β β βBootstrapInstaller β β β
β β β /usr /home /tmp βββ β (Download + Extract)β β β
β β ββββββββββββββββββββββ ββββββββββββββββββββββββ β β
β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β libtermux_jni.so (C++ Native Layer) β β β
β β β PTY Β· Process Fork Β· Symlinks Β· chmod β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β App Private Storage: filesDir/libtermux/ β β
β β βββ usr/bin/bash, python3, node ... β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- Fork the repo
- Run
./scripts/setup_dev.sh - Create a feature branch:
git checkout -b feature/amazing-feature - Run tests:
./gradlew :core:testDebugUnitTest - Push and open a Pull Request
Copyright 2026 LibTermux Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0