Self-hosted remote desktop over QUIC for Windows, macOS and X11 Linux, with hardware video encoding and a browser console.

206
74
Rust
MIT
1 day old

Overview

Airhand is a remote desktop system in which one binary works as both host and controller. It targets people who want low-latency desktop access without a third-party cloud service: you deploy a small relay server with Docker Compose, and clients connect to it over QUIC/TLS.

The host captures the screen only when it changes, encodes with hardware AV1/HEVC/H.264 where available, and falls back to OpenH264. The controller decodes with WebCodecs and paints into a canvas; the remote cursor shape is mirrored locally, so cursor movement does not wait for the network. Audio from the host's system output is streamed as Opus. Clipboard text sync, shortcut injection, multiple monitors and a multi-screen overview are included; clients and web console share one React UI (design overview).

Quick start

  1. On a machine both peers can reach, deploy the relay server and note the certificate fingerprint:

    docker compose up -d
    docker compose logs airhand | grep fingerprint
    

    The server listens on UDP 4433 (quick start).

  2. Build the desktop client with the relay address and fingerprint compiled in. On Windows:

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

    The result is client/src-tauri/target/release/airhand.exe. Rust, Node.js 20+ and CMake are required; macOS and Linux need their own Tauri dependencies, and Linux X11 also needs PulseAudio and GStreamer development files (build requirements).

  3. Run Airhand on the remote computer; it starts as a tray icon. Right-click it to read the 6-digit control code. Run it on your computer, choose Switch to controller, and enter the code.

If you do not want to install the controller, run the web console in web/ instead: AIRHAND_SERVER=relay.example.com:4433 AIRHAND_SERVER_FP=<fingerprint> docker compose up -d, then open port 8080 in a browser (web console).

Platform and permission constraints

  • The host supports Windows and X11 Linux desktops; Wayland is only usable for X11/XWayland applications. The Linux host currently encodes with OpenH264 only, without VA-API or NVENC.
  • A macOS host needs Screen & System Audio Recording and Accessibility permissions, and the login window and lock screen cannot be captured. On Windows the same applies to UAC prompts and the lock screen without elevated privileges; Ctrl+Alt+Del cannot be injected (known limitations).
  • The client and server must be built from the same version; a protocol mismatch is detected and reported (protocol versions).
  • The server address and certificate fingerprint are compiled into the client, so changing the relay requires a rebuild. An empty fingerprint disables certificate verification and should be used for development only (building the client).
  • The relay server terminates TLS and can see session contents, so it should run on a machine you trust. Clipboard sync is text-only; microphone audio is not forwarded.
  • The desktop client keeps no configuration file; settings live in memory, and the console's temporary WebView data is removed on exit (zero files). The project is MIT licensed.

HotRepo's take

Airhand appeared in HotRepo's Rust daily new-project list on 2026-11-02, recording 102 new stars and 37 new forks in a growth window starting 2026-11-01; the full-language daily rank was not recorded. The sampled star curve shows 102 stars held through the first 12 hourly points and then 204 at the last observation, so there is one visible jump rather than a day-long trend. The design choices worth noting are architectural: per-frame acknowledgements with in-flight frame caps, frame skipping to the newest frame under congestion, and separate queues for control, audio and video messages (video pipeline). The README also distinguishes measured figures from estimates, such as ~7 ms for a hardware AV1 encode and a ~70 ms default audio lag. Ongoing development and protocol churn are real caveats for anyone considering it as a production tool.

Written by AI from the project's README, updated . The project's own docs are the source of truth.