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 immediately on press and detects quick second presses as double-clicks.
  • Drag mode holds the primary button while the pointer moves.
  • Mouse movement, double-click, wheel, and horizontal scroll are supported.
  • Copy reads the X11 clipboard into the browser clipboard; Paste and browser paste events send text to the X11 clipboard. Install xclip or xsel in the environment running TermuxDesk to enable clipboard support.
  • 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.2.tar.gz (19.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.2-py3-none-any.whl (20.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: termux_desk-0.1.2.tar.gz
  • Upload date:
  • Size: 19.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.2.tar.gz
Algorithm Hash digest
SHA256 5b8cfe6b8b45a456f1eb47dbf5c12e8b16e1d405b008180dddf7afeb9c6f37f9
MD5 d1f517076b30d9858ab2aad2e0b1daed
BLAKE2b-256 19fff2e56e129b88c896c4d44180d700447094beb4f02c270ee893b99d22d0d8

See more details on using hashes here.

File details

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

File metadata

  • Download URL: termux_desk-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 20.3 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 262126d5a740f736ca6cda26350dd4dc5b4e994b9004efe6f6c633f67ddb1d20
MD5 13605ed5ab2cfe2bcd95a188b5981340
BLAKE2b-256 459919e6ea9f6f2f93bdde0c8bb84614e91c3bdae0ee152f679c4d4c8952eb58

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