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/YBeeTeam/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.0.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.0-py3-none-any.whl (17.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: termux_desk-0.1.0.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.0.tar.gz
Algorithm Hash digest
SHA256 044782ec6c6c56a767101e1827fdd6f44c1ea8fecd7e7272cc4a7841424b616d
MD5 4b6ddd21d4011f2fc8716044ba3bc0ce
BLAKE2b-256 c451ebbd09572741d46e15b6421c341cecbc72cf1e632a52d9f1b38b2e31ef15

See more details on using hashes here.

File details

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

File metadata

  • Download URL: termux_desk-0.1.0-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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2c5332f47de3d2ef741fedf8aa1a51d63642b3ba25847ae1a01c9d46110c3641
MD5 85dc7d873d3e4e94c7c9102593808f5c
BLAKE2b-256 27e4f7d5cfb4605283c0802975f76583c7f3b53acbe3ce4fd5a90a89ddc6a5c5

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