ZXTouch Rootless is an open-source framework that simulates touch events at the system level — no per-app injection. Script it from any language over a socket, replay recorded gestures, match images, and read the screen with OCR. Now fully ported to rootless & roothide jailbreaks.
simultaneous fingers — true system multitouch
event latency — fast enough for live remote
socket port — drive it from any language
apps injected — zero per-app hooks
One tweak, one socket, a full automation toolkit. Every capability works across the entire OS — home screen, any app, any game.
Drive up to 19 simultaneous fingers with independent down / move / up phases. Pinch, rotate, drag and complex game gestures are first-class — batch them in a single frame with touch_with_list().
device.touch(TOUCH_DOWN, 5, 400, 400) device.touch(TOUCH_MOVE, 5, 400, 600) device.touch(TOUCH_UP, 5, 400, 600)
A clean socket protocol on port 6000, plus a batteries-included Python module. If it can open a TCP socket, it can automate the device.
Capture real touch sessions and replay them perfectly — from the floating panel, the API, or iOS Shortcuts.
Template-match on the live screen, Accelerate-framework fast. Find a button, tap it — no fragile coordinates.
Read text straight off the screen — multi-language, accurate or fast modes. No cloud, nothing leaves the device.
Trigger recorded scripts from iOS Shortcuts & automations — on a schedule, an NFC tag, or a tap.
Run commands as root from your scripts with run_shell_command() and glue device state into automation.
Double-click volume-down anywhere in iOS to summon an on-screen panel: run saved scripts, start/stop recording, and manage settings on the go.
Control the device live over the network — fast enough for real-time mirrored input from a computer.
Read RGB at any pixel, fire native alert boxes & toasts, type into fields and move the cursor — all from a script.
A complete reference for the Python client, the touch model, computer vision, and the on-device tools.
Install the tweak (see Installation), make sure python3 from the Procursus repo is present, then connect to the daemon on port 6000. The zxtouch Python module ships with the tweak.
from zxtouch.client import zxtouch from zxtouch.touchtypes import * import time device = zxtouch("127.0.0.1") # on-device, or your iPhone IP for remote # a one-finger swipe down: down → move → up device.touch(TOUCH_DOWN, 5, 400, 400) time.sleep(0.4) device.touch(TOUCH_MOVE, 5, 400, 600) device.touch(TOUCH_UP, 5, 400, 600) device.disconnect()
The tweak runs a daemon listening on port 6000. Construct a client with the target IP — "127.0.0.1" when your script runs on the device itself, or the iPhone's LAN IP to drive it remotely from a computer.
(success: bool, data_or_error) — check the first element before trusting the second.get_screen_size() / get_screen_scale() to write resolution-independent scripts.device.disconnect() when done to close the socket cleanly.Each touch carries a type (TOUCH_DOWN / TOUCH_MOVE / TOUCH_UP), a finger index from 1–19, and x, y coordinates. A gesture is a down, any number of moves, then an up on the same finger. For multi-finger gestures, dispatch several events in one frame with touch_with_list().
device.touch_with_list([ {"type": TOUCH_DOWN, "finger_index": 1, "x": 350, "y": 600}, {"type": TOUCH_DOWN, "finger_index": 2, "x": 450, "y": 700}, ]) for i in range(20): device.touch_with_list([ {"type": TOUCH_MOVE, "finger_index": 1, "x": 350-i*8, "y": 600-i*8}, {"type": TOUCH_MOVE, "finger_index": 2, "x": 450+i*8, "y": 700+i*8}, ]) device.accurate_usleep(16000) # ≈ one 60fps frame, precise
Stop hardcoding coordinates. image_match() locates a template on the live screen and returns its bounding box; ocr() reads on-screen text so scripts react to real state. pick_color() samples a pixel's RGB.
ok, m = device.image_match("/var/mobile/button.png", acceptable_value=0.8, max_try_times=4) if ok and float(m["width"]) > 0: # width==0 means no match x = float(m["x"]) + float(m["width"]) / 2 y = float(m["y"]) + float(m["height"]) / 2 device.touch(TOUCH_DOWN, 1, x, y) device.touch(TOUCH_UP, 1, x, y) # read a score region (x, y, w, h), accurate mode ok, lines = device.ocr((40, 120, 300, 60), recognition_level=0) print(lines) # → ["Score: 1240"]
Type into the focused field, nudge the cursor, switch apps, and surface native feedback — alert boxes and four styles of toast.
from zxtouch.toasttypes import * device.switch_to_app("com.apple.MobileSMS") device.insert_text("sent by zxtouch") device.insert_text("\b\b") # backspace x2 device.move_cursor(-3) # move left 3 device.show_toast(TOAST_SUCCESS, "Done!", 1.5) device.show_alert_box("ZXTouch", "Message ready", 3)
Double-click volume-down anywhere in iOS to open the ZXTouch panel — run saved scripts, start/stop recording, and adjust settings without a computer. Recordings save as replayable ZXTouch scripts.
Programmatically, start_touch_recording() begins capture (double-click volume-down or call stop_touch_recording() to end), and play_script(path) replays one. Use force_stop_script_play() to abort.
from zxtouch.touchtypes import *
TOUCH_DOWN — finger landsTOUCH_MOVE — finger dragsTOUCH_UP — finger liftsfrom zxtouch.toasttypes import *
TOAST_SUCCESS · TOAST_ERRORTOAST_WARNING · TOAST_MESSAGETOAST_BUTTOM — default position (0)from zxtouch.client import zxtouch from zxtouch.touchtypes import * import time device = zxtouch("127.0.0.1") try: while True: device.touch(TOUCH_DOWN, 1, 390, 844) device.touch(TOUCH_UP, 1, 390, 844) time.sleep(1) finally: device.disconnect()
from zxtouch.client import zxtouch from zxtouch.touchtypes import * import time device = zxtouch("127.0.0.1") while True: ok, m = device.image_match("/var/mobile/claim.png") if ok and float(m["width"]) > 0: x = float(m["x"]) + float(m["width"])/2 y = float(m["y"]) + float(m["height"])/2 device.touch(TOUCH_DOWN, 1, x, y) device.touch(TOUCH_UP, 1, x, y) break time.sleep(0.5)
from zxtouch.client import zxtouch from zxtouch.toasttypes import * import time device = zxtouch("127.0.0.1") device.switch_to_app("com.apple.MobileSMS") time.sleep(2) device.insert_text("sent by zxtouch") device.show_toast(TOAST_SUCCESS, "Typed!", 1.5) device.disconnect()
from zxtouch.client import zxtouch device = zxtouch("127.0.0.1") ok, bat = device.get_battery_info() if ok and float(bat["battery_level"]) < 0.2: device.show_alert_box("ZXTouch", "Battery under 20% — pausing.", 3) else: device.play_script("/var/mobile/farm.zxs")
Install from the Sileo repo (recommended) or grab a .deb from GitHub Releases. The repo ships both rootless and roothide builds.
Tap Add to Sileo above, or in Sileo go to Sources → + and add https://epic0001.github.io/zxtouchrootless/. Alternatively, download _rootless.deb from Releases.
In Sileo, install ZXTouch (rootless build), or over SSH / NewTerm:
$ dpkg -i zxtouch_*_rootless.deb $ killall -9 SpringBoard
Add the Procursus repo and install python3 — required to run scripts on-device.
Double-click volume-down — the floating panel appears. The daemon is now listening on 127.0.0.1:6000.
Other rootless setups on iOS 15–16.6.1 will likely work — reports welcome on GitHub or Discord.
Join the community shaping iOS automation — share scripts, report device compatibility, and help bring ZXTouch to new jailbreaks.