Production-Grade Playwright Automation on Android Termux
Dual-engine (Python & Node.js) Chromium browser automation on ARM64 mobile hardware without root, PRoot, or X11 virtualization.
Select your runtime and run the 1-line installation command in Termux:
🐍 Python Edition (PyPI):
pip install termux-playwright && termux-playwright-install
☕ Node.js / TypeScript Edition (npm):
npm install termux-playwright && npx termux-playwright install
The Problem: Why Upstream Playwright Fails on Android
Upstream Playwright is hardcoded to strictly support desktop Linux glibc, macOS, and Windows. When invoked on Android Termux, it fails due to incompatible pre-compiled binaries, Bionic libc syscall differences, dynamic shared memory (/dev/shm) crashes, and Android kernel process reaping.
The Architectural Solution
Termux-Playwright provides native Bionic binary orchestration, targeted session process isolation (ProcessReaper), persistent disk ledger recovery (.tp_ledger), prototype-safe anti-bot stealth, and flash memory wear protection.
Key Capabilities & Built-in Hardening
Zero-Root Native Execution
Orchestrates Termux-compiled Chromium and Node.js without PRoot overhead.
Persistent Disk Ledger
Design properties 100% orphan process reaping across hard kernel crashes (SIGKILL / LMK).
Prototype-Safe Stealth
Deletes navigator.webdriver from prototype to bypass Cloudflare Turnstile & DataDome.
eMMC Hardware Protection
Injects RAM-based caching to prevent mobile flash wear.
Virtualenv Diagnostic Repair
Pre-flight diagnostics and auto-repair guidance for venv environments.
Dual-Engine Production Code Recipes
🐍 Python Canonical Recipe (`asyncio`):
import asyncio
from termux_playwright import async_playwright_termux, launch, setup_stealth_context
async def main():
async with async_playwright_termux() as p:
# Launch hardened Chromium with anti-bot stealth
browser = await launch(p, headless=True, stealth=True)
context = await setup_stealth_context(browser)
page = await context.new_page()
await page.goto("https://news.ycombinator.com", timeout=45000)
print(f"Title: {await page.title()}")
await browser.close()
if __name__ == "__main__":
asyncio.run(main())
☕ Node.js / JavaScript Canonical Recipe (`async/await`):
const { launch, setupStealthContext, blockHeavyResources, forceGarbageCollection } = require('termux-playwright');
async function main() {
// Automatically provisions session ledger, eMMC RAM cache, and WakeLock
const browser = await launch({
headless: true,
stealth: true,
lowMemoryMode: true,
wakeLock: true
});
try {
const context = await setupStealthContext(browser);
const page = await context.newPage();
// Abort heavy media to save mobile CPU & bandwidth
await blockHeavyResources(page, { images: true, media: true, fonts: true });
await page.goto('https://news.ycombinator.com', { timeout: 45000, waitUntil: 'domcontentloaded' });
console.log('Title:', await page.title());
// Periodic V8 heap flush for long-running mobile scrapers
forceGarbageCollection();
} finally {
await browser.close();
}
}
main().catch(console.error);
Frequently Asked Questions (FAQ)
Q: Can I use this for 24/7 autonomous scraping on an old Android phone?
Yes! Termux-Playwright includes automated CPU WakeLock handling (`wake_lock=True`), eMMC RAM-disk caching, and V8 heap limiters to ensure 24/7 background operation without kernel LMK process termination.
Q: Why not use PRoot Linux (Ubuntu / Debian)?
PRoot intercepts all system calls using `ptrace`, creating severe 3x~5x CPU latency, 60% higher RAM consumption, and broken `/dev/shm` shared memory. Termux-Playwright runs directly on native Android Bionic libc for maximum speed.