Skip to main content

A web-based remote desktop for Termux and PRoot X11 environments

Project description

TermuxDesk

Python 3.9+ PyPI License: MIT

A lightweight, web-based remote desktop for Termux and PRoot X11 environments.

TermuxDesk captures an existing X11 display with Pillow, streams JPEG frames through an aiohttp WebSocket, and injects mouse and keyboard events with the XTest extension through python-xlib. It does not need root or sudo.

Project status: 0.1.0 is an alpha release. Test it with your desktop and window manager before relying on it.

Demo

TermuxDesk browser viewer demo

Requirements

  • Python 3.9 or newer
  • A running X11 server with the XTest extension
  • DISPLAY set to that server, such as :0
  • cloudflared only when using --tunnel

TermuxDesk provides the remote viewer; it does not start Termux:X11, Xvfb, a desktop environment, or a window manager.

Install

From PyPI:

python -m pip install termux-desk

From a checkout:

python -m pip install .

Termux one-liner:

curl -fsSL https://raw.githubusercontent.com/amirghm/termux-desk/main/install.sh | bash

The installer must run in Termux itself, not inside a Debian/Ubuntu PRoot. This matters because PRoot's apt repositories do not provide Termux's python package. Run Termux package installation first, then enter your PRoot if that is where the X11 session runs.

Quick Start

Start your X11 environment, identify its display, and run:

export DISPLAY=:0
termux-desk start

Open http://127.0.0.1:8765 in a browser on the same device.

To listen on the LAN:

termux-desk start --host 0.0.0.0

To create a temporary HTTPS URL:

termux-desk start --tunnel

Security warning: TermuxDesk 0.1.0 has no built-in authentication. Anyone who can reach the URL can view and control the X11 session. A Cloudflare Quick Tunnel URL is public. Share it only with trusted people, stop it after use, and prefer Cloudflare Access or another authenticated proxy for ongoing access.

Browser Controls

  • Click mode sends primary clicks on tap or mouse release.
  • Drag mode holds the primary button while the pointer moves.
  • Mouse movement, double-click, wheel, and horizontal scroll are supported.
  • Keyboard events are sent while the viewer page has focus.
  • The Help button shows the controls in the viewer.

Browser and operating-system reserved shortcuts may not reach the remote desktop.

CLI Reference

termux-desk start [--host HOST] [--port PORT] [--display DISPLAY]
                  [--fps FPS] [--quality 1..95] [--tunnel]
Option Default Description
--host 127.0.0.1 HTTP listen address
--port 8765 HTTP listen port
--display $DISPLAY X11 display name
--fps 12 Maximum capture rate
--quality 70 JPEG quality from 1 to 95
--tunnel off Start a Cloudflare Quick Tunnel

Use termux-desk --version to print the installed version and Ctrl+C to stop the server and tunnel.

Python API

The public API has no third-party import side effects. Runtime dependencies and the X11 connection are loaded when the server starts.

from termux_desk import TermuxDeskServer

server = TermuxDeskServer(
    host="127.0.0.1",
    port=8765,
    display=":0",       # defaults to the DISPLAY environment variable
    fps=12,
    quality=70,
)
server.run()

For an existing asyncio application:

server = TermuxDeskServer()
await server.start()
print(server.local_url)
# ... application work ...
await server.stop()

termux_desk.run_server(**options) is a blocking convenience function. TermuxDeskError is raised for missing dependencies, an unset or unreachable display, missing XTest support, and tunnel startup failures.

Troubleshooting

DISPLAY is not set

Set it to the display used by your X11 session:

export DISPLAY=:0

Could not connect to X11 display

Verify the server is running, the display number is correct, and the process has permission to connect. From a PRoot environment, preserve or explicitly set DISPLAY.

cloudflared was not found

Install it in Termux:

pkg install cloudflared

Pillow fails to install in Termux

Install its native build dependencies, then retry:

pkg install python clang make pkg-config libjpeg-turbo libpng
python -m pip install Pillow

Architecture

The root page serves a viewer embedded directly in termux_desk.server; there is no runtime template or static-file lookup. Each WebSocket client receives JPEG frames and sends small JSON input messages. Pointer coordinates are normalized in the browser, validated by the server, and scaled to the current X11 screen dimensions before XTest injection.

Contributing

  1. Fork and clone the repository.
  2. Create a virtual environment and run python -m pip install -e '.[dev]'.
  3. Make a focused change and add tests.
  4. Run pytest and python -m build.
  5. Open a pull request describing behavior changes and the X11 environment used for manual testing.

Bug reports should include Python version, Termux/PRoot distribution, X server, window manager, browser, and the exact command used.

License

MIT © 2026 TermuxDesk contributors.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

termux_desk-0.1.1.tar.gz (17.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

termux_desk-0.1.1-py3-none-any.whl (17.4 kB view details)

Uploaded Python 3

File details

Details for the file termux_desk-0.1.1.tar.gz.

File metadata

  • Download URL: termux_desk-0.1.1.tar.gz
  • Upload date:
  • Size: 17.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.2

File hashes

Hashes for termux_desk-0.1.1.tar.gz
Algorithm Hash digest
SHA256 214d882544f6d6209642b9e46be090f220247201e93f0cfbfe27947f3d72641f
MD5 b1da530f3c961f02771050cc7bc91b1d
BLAKE2b-256 1ecd707a64f32d1125f1bf06f6d9b7eff20725bfd1b63fb0aa0b0e37e87e1086

See more details on using hashes here.

File details

Details for the file termux_desk-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: termux_desk-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 17.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.2

File hashes

Hashes for termux_desk-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d290eccf976f332e7ce2688cf3a6e0915eee40df658bc2dacbc97ca7682aa91f
MD5 c152d97800683f75c3f4a415e435bf6e
BLAKE2b-256 45dc8b9a93a166c21b923cd1bd63149b2902fb8deb008a7309749da910e29283

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page