Zed and Waypipe for Remote GUI Development

2 min read Original article ↗

My laptop is old and under-powered and crappy and I love it. It’s a 10 year old Thinkpad T470s. Super light, great keyboard, battery lasts for ages (replaceable!) - but it’s dog slow. On the other hand, my desktop is a beast.

So what to do when I’m on the road for the holidays and want to ignore my family by hacking on my current project Gelly: a GTK + Rust application? Working directly on the Thinkpad is akin to computer torture: a clean build takes upward of 5 minutes and rust-analyzer alone maxes out the laptop’s 16 GB of ram.

Zed has a really nice remote development experience meaning I can do all the actual editing on the desktop (thanks to Tailscale) - that includes offloading rust-analyzer. I have a simple Zed task to run just dev to do the build. Now for the tricky part: running the application.

If I were doing web development (unfortunately a reality for the day job) this would simply be a matter of pointing my browser to the desktop’s address. However launching a GUI application on the remote desktop doesn’t help much if I can’t see the display. Enter waypipe: a project most easily described as X forwarding for Wayland. With Waypipe, one can launch a remote application over SSH like so:

waypipe ssh user@remote gnome-calculator

And it will forward the window to the local Wayland display! It’s fast and responsive and acts like a normal application window. Much more convenient than a full remote-desktop session.

Now with a single command in Zed (alt + t) I can compile and launch the application and the window appears on my laptop. It’s the same exact workflow I have on my desktop, but on my laptop, but actually it’s on the desktop still! Loving this setup.

Here’s the code for the just recipe:

dev-remote host:
    #!/usr/bin/env bash
    set -euo pipefail
    echo "Building locally..."
    cargo build
    echo "Launching on remote display..."
    DEV_HOST=$(hostname -f)
    BINARY_PATH="{{justfile_directory()}}/target/debug/gelly"
    WAYLAND_DISPLAY_VAR="${WAYLAND_DISPLAY:-wayland-0}"
    ssh {{host}} "WAYLAND_DISPLAY=$WAYLAND_DISPLAY_VAR RUST_LOG='debug,glycin=off,glycin_utils=off' waypipe -n ssh $DEV_HOST $BINARY_PATH"