Skip to content
sqlpxcPublic

About

High-performance, low-latency remote desktop QUIC transport · hardware encoding and decoding · up to 120 fps Windows · macOS · Linux · Android · browser

Resources

Security policy

Stars

988 stars

Watchers

101 watching

Forks

Repository files navigation

Airhand

Airhand

High-performance, low-latency remote desktop
QUIC transport · hardware encoding and decoding · up to 120 fps
Windows · macOS · Linux · Android · browser

English · 简体中文


Airhand is a high-performance, low-latency remote desktop: the screen is encoded on the GPU (AV1 / HEVC / H.264) at up to 120 fps and sent over QUIC; when the network slows down it skips to the latest frame instead of letting lag pile up; and the mouse pointer is drawn locally, so it moves without delay.

The same program is both the host (the device being controlled) and the controller (the device you control it from). The two sides meet through a relay server that you deploy yourself. It's small, and Docker Compose deploys it with one command. Enter the other side's 6-digit control code to connect.

Note

Work in progress (0.2.2). The protocol still changes between versions, so the clients and the server need to be the same version; a mismatch is detected and reported (see Protocol versions).

Performance

Every stage from capture to display is built for low latency:

  • Hardware encoding and decoding: the host encodes on the GPU (NVENC / Quick Sync / AMF, VideoToolbox, MediaCodec) in low-latency mode without B-frames; the controller decodes on the GPU (WebCodecs / MediaCodec). Measured with a 4K screen streamed at 1080p, hardware AV1 encoding takes about 7 ms per frame (RTX graphics card)
  • The best format: AV1 > HEVC > H.264, automatically picking the most efficient format both sides support; scaling and color conversion use SIMD, and all buffers are reused
  • No lag build-up: the host limits frames in flight (≈ RTT × frame rate + 2) and skips to the latest frame on a slow network; adaptive bitrate backs off under congestion and recovers gradually
  • QUIC + BBR: BBR congestion control is steadier than Cubic on lossy networks such as Wi-Fi or long-distance links; control messages, audio and video are queued separately, so mouse input and pings never wait behind a large frame; the relay only forwards bytes and never parses the video
  • Decode and show: the decoder runs in low-latency mode, and each frame is drawn to a desynchronized canvas as soon as it's decoded, without waiting for vsync
  • Local pointer: the remote cursor's shape is mirrored locally, and moving it happens locally
  • Low bandwidth: no frames are sent while the screen is still, so an idle desktop uses almost nothing; sessions that aren't on screen drop to 5 fps

See How it works → Video for details.

Features

  • Windows system service: the lock screen, the sign-in screen and UAC prompts can be seen and controlled, and the computer can be reached after boot, before anyone signs in
  • Fixed control codes: they survive restarts, upgrades and even server restarts until you change them yourself
  • Console: browser-style tabs to control several computers at once, plus a multi-screen overview to watch them all. Computers you've connected to are saved and reconnect with one click; if one is offline, it connects as soon as it comes back
  • Web console: the controller can also run in Docker and be used from a browser, with nothing to install on the computer you control from
  • Android: control computers and phones from a phone as a trackpad or touchscreen, or share your own screen to get help (you approve each connection by default); watch on a TV with the remote
  • Audio: the host's system audio plays on the controller (Opus + adaptive jitter buffer), with optional A/V sync for watching videos
  • Handy tools: two-way clipboard sync, typing the clipboard as keystrokes, system shortcuts (Win, Alt+Tab, Ctrl+Shift+Esc…), multiple monitors, keyboard lock in fullscreen, quality presets
  • Secure by default: TLS 1.3 with certificate pinning, brute-force protection for control codes; the host always sees who is connected and can disconnect them with one click
  • Leaves nothing behind: the host is just a tray icon and doesn't start a WebView; everything worth keeping is in one config.toml, other runtime files are deleted on exit, and nothing is left after uninstalling (Windows has an uninstaller, macOS has "Uninstall Airhand…" in the menu, Linux takes two commands)
  • English and Chinese: follows the system language; notices from the other computer and the server also appear in your language

Platforms

Platform Host Controller Notes
Windows 10 / 11 ✅ ✅ Installed; the host runs as a system service
macOS 13+ ✅ ✅ The host needs the Screen & System Audio Recording and Accessibility permissions
Linux ✅ ✅ The host supports X11 desktops only, with software encoding for now
Android 7+ phones / tablets ✅ ✅ Can only be watched until the accessibility service is turned on; the controller connects to one device at a time
Android TV / Google TV — View only Operated entirely with the remote
Browser (web console) — ✅ Chrome / Edge, Safari 16.4+, Firefox 130+

See Known limitations for platform-specific caveats.

How it works

flowchart LR
    host["Host<br>Windows / macOS / Linux / Android"]
    relay["Relay server<br>airhand-server (Docker)"]
    ctrl["Controller<br>desktop console / web console / Android"]
    host <-->|"QUIC · UDP 4433"| relay
    relay <-->|"QUIC · UDP 4433"| ctrl
Loading

The host connects to the relay server and gets a 6-digit control code; the controller uses that code to find it. The server only registers codes, pairs sessions and forwards bytes; it never parses the video. Both the host and the controller connect out to the server, so neither needs an open port or a public IP. See How it works for details.

Quick start

You need:

  • A machine both sides can reach, with Docker and UDP 4433 open
  • Rust, Node.js 20+ and CMake to build the client (per-platform requirements in Building)

1. Deploy the relay server

git clone https://github.com/sqlpxc/airhand.git
cd airhand
docker compose up -d
docker compose logs airhand | grep fingerprint   # note the certificate's SHA-256 fingerprint

The certificate and the control-code database live in data/. Keep that directory: with a new certificate, clients you've already built can no longer connect. Server settings are in Deployment.

2. Build the client

Compile in the server address and the fingerprint from step 1.

Windows (PowerShell):

cd client
npm install
$env:AIRHAND_SERVER    = "relay.example.com:4433"
$env:AIRHAND_SERVER_FP = "<fingerprint from step 1>"
npm run tauri build

macOS / Linux:

cd client
npm install
export AIRHAND_SERVER=relay.example.com:4433
export AIRHAND_SERVER_FP=<fingerprint from step 1>
npm run tauri build

The packages are under client/src-tauri/target/release/bundle/:

System Package
Windows nsis/Airhand_<version>_x64-setup.exe
macOS macos/Airhand.app, dmg/Airhand_<version>_<arch>.dmg
Linux deb/Airhand_<version>_amd64.deb

The server address and fingerprint can also be changed later in config.toml. For the Android APK, see Building → Android.

3. Connect

  1. Install Airhand on both computers (on Windows run the installer, which needs administrator rights; on macOS grant the permissions it asks for the first time)
  2. On the computer to be controlled, right-click the tray icon (on macOS, click the menu bar icon) to see its 6-digit control code
  3. On your computer, choose Open console from the tray menu (Switch to controller on macOS / Linux) and enter the code

The full guide is in Usage.

Without installing a client: the web console

Start the web console on any machine with Docker and use it from a browser:

cd web
AIRHAND_SERVER=relay.example.com:4433 AIRHAND_SERVER_FP=<fingerprint> docker compose up -d

Open http://localhost:8080 on that machine, or https://<its address>:8080 from other computers. For the access password, the HTTPS certificate and reverse proxies, see Deployment → Web console.

Documentation

Document Contents
Usage Host, Windows installation, configuration file, uninstalling, console, quality, language
Deployment Relay server settings, web console, reverse proxies
Android Controlling from a phone, sharing the phone, gestures, TVs
Building Per-platform requirements and packages, signing, APK
How it works Architecture, source layout, Windows service, video and audio pipelines, A/V sync, files on disk
Security Encryption and pinning, brute-force protection, control codes and resume tokens
Known limitations Known issues by platform
Development Tests, debugging tools, project conventions

Security notes

  • Everything runs over TLS 1.3 (QUIC), and clients verify the server by its certificate fingerprint. A client built without a fingerprint doesn't verify the server; use that for development only
  • The relay server can see session contents (TLS terminates at the server), so run it on a machine you trust; the same goes for the web console
  • A control code is a key: the Windows host runs as SYSTEM, so whoever has the code controls the computer with administrator rights. Give it only to people you trust; the host's tray always shows who is connected and lets you disconnect them or change the code

See Security for details.

Contributing

Directory Contents
crates/ The protocol (airhand-proto) and the client-to-relay link (airhand-link)
server/ Relay server
web/ Web console service
client/ Desktop client: Tauri (Rust) + React UI, which the web console uses too
android/ Android app (Kotlin + Jetpack Compose) and its Rust core

How to run the tests, the debugging tools and the project conventions (protocol versions, UI strings…) are in Development.

License

MIT

About

High-performance, low-latency remote desktop QUIC transport · hardware encoding and decoding · up to 120 fps Windows · macOS · Linux · Android · browser

Resources

Security policy

Stars

988 stars

Watchers

101 watching

Forks

Releases

Packages

Contributors

Languages