ghost provides remote desktop and game streaming for Linux hosts. A user
signs in from the spectre client, and ghost starts that user's desktop
headless on the host and streams it back over GDP, ghost's QUIC-based
protocol.
- Real desktops. Sessions run unmodified GNOME, KDE Plasma or LXQt, or a single app such as a terminal or Steam Big Picture.
- Hardware encoding. H.264, H.265 and AV1 on VA-API or NVENC, with an x264 fallback, plus PyroWave for wired LANs and an optional lossless layer that keeps settled text pixel-exact.
- Full input. Keyboard, pointer, clipboard, gamepads and microphone are forwarded, and session audio is sent back.
- System logins. Users authenticate through PAM and get a real logind session, one per account.
- Optional broker. Veil gives users one place to sign in to many hosts, with an admin UI, a browser client and PXE-booted thin clients.
| Process | Role |
|---|---|
ghostd |
Host agent, unprivileged. Authenticates users through ghostauth and has ghostseat start their sessions. |
wraith |
Session agent, one per user. Captures and encodes the desktop, and injects input. |
spectre |
Client for Linux, Windows and macOS. Decodes and presents the stream. |
spectre-qt |
Login launcher for spectre. |
veild |
Optional broker (Veil). |
wraith never draws a desktop itself. It attaches as a client to the session's own compositor, through one of three capture backends:
| Backend | Compositor | Session types |
|---|---|---|
screencast-gnome |
gnome-shell --headless |
GNOME |
screencast-kwin |
kwin_wayland --virtual |
KDE Plasma |
screencast-ext |
Any compositor with ext-image-copy-capture-v1 |
Terminal, Steam Big Picture, LXQt (labwc) |
ARCHITECTURE.md gives the full picture.
| Path | Contents |
|---|---|
host/ |
The server side. A Rust workspace (ghostd, ghostseat, ghostlogin, veil/ and shared crates), plus wraith/ (C++) and proto/ (host-internal schemas) |
client/ |
spectre, spectre-qt, and wisp/ (the thin-client image) |
libgdp/ |
The shared GDP library: QUIC transport, framing, negotiation, and the wire schemas |
packaging/ |
Files installed on hosts (systemd, PAM, polkit, udev, session profiles, configs), and the macOS client build |
docs/ |
Install guides, reference, design docs, decision records, and the protocol spec |
You need CMake 3.20 or later, a C++20 compiler, and a stable Rust toolchain. The host side needs SDL3 and ngtcp2 with its OpenSSL crypto helper. Supported distributions are Ubuntu 26.04 or later (used by CI), Fedora 43 or later, and current Arch.
Ubuntu / Debian
sudo apt install build-essential cmake ninja-build pkg-config git curl \
protobuf-compiler libprotobuf-dev libssl-dev openssl \
libngtcp2-dev libngtcp2-crypto-ossl-dev \
wayland-protocols libwayland-dev libxkbcommon-dev \
libdrm-dev libva-dev libgbm-dev libx264-dev libzstd-dev \
libtomlplusplus-dev libpipewire-0.3-dev libopus-dev \
libei-dev libsystemd-dev libfuse3-dev libpcsclite-dev \
libsdl3-dev libavcodec-dev libavutil-dev libvulkan-dev glslang-tools \
qt6-base-dev libpam0g-dev cargoFedora
Enable RPM Fusion (free) first. Fedora's own ffmpeg-free-devel lacks
the H.264 decoder, and x264 isn't packaged in Fedora itself.
sudo dnf install gcc gcc-c++ cmake ninja-build pkgconf-pkg-config git curl \
protobuf-compiler protobuf-devel openssl-devel openssl \
ngtcp2-devel ngtcp2-crypto-ossl-devel \
wayland-protocols-devel wayland-devel libxkbcommon-devel \
libdrm-devel libva-devel mesa-libgbm-devel x264-devel libzstd-devel \
tomlplusplus-devel pipewire-devel opus-devel \
libei-devel systemd-devel fuse3-devel pcsc-lite-devel \
SDL3-devel ffmpeg-devel vulkan-loader-devel vulkan-headers glslang \
qt6-qtbase-devel pam-devel cargoArch
sudo pacman -S --needed base-devel cmake ninja pkgconf git curl \
protobuf openssl libngtcp2 \
wayland-protocols wayland libxkbcommon libdrm libva \
mesa x264 zstd tomlplusplus libpipewire opus libei systemd-libs fuse3 pcsclite \
sdl3 ffmpeg vulkan-icd-loader vulkan-headers glslang \
qt6-base pam rustAt runtime, a host needs the compositor of each session type it offers
(labwc, GNOME or Plasma), and foot for the terminal session; a type
whose programs are missing is not listed. Pasting files across and shared
folders need FUSE (fusermount3) on both ends, except that a Windows
client pastes the host's files without it; libfuse3's headers at build
time (optional: without them both ends build and leave it out). Smart card
forwarding needs pcscd on both ends, and pcsc-lite's headers at build
time (optional likewise).
make # build into build/ (RelWithDebInfo)
make test # C++ unit tests (libgdp, wraith, spectre)
make debug # unoptimized build into build-debug/Run the Rust tests with cargo test --workspace from host/. The client
alone also builds on macOS (packaging/macos/)
and Windows (packaging/windows/).
make deb, make rpm and make arch build the Ubuntu, Fedora and Arch
packages into target/. To release, make bump V=x.y.z sets the
version (in CMakeLists.txt, the Cargo workspace and debian/changelog);
commit that, then push a vx.y.z tag. The tag builds those packages, the
Windows zip and the macOS .dmg, and publishes them as a GitHub Release
(.github/workflows/release.yml).
| ARCHITECTURE.md | Processes, the login path, and the rules the design depends on |
| docs/install/ | Setup guides |
| docs/reference/ | Configuration, session profiles, command line, files and paths |
| docs/design/ | How each area works, and its limitations |
| docs/adr/ | Architecture decision records |
| docs/spec/gdp-spec.md | The GDP wire protocol |
| TODO.md | Known gaps |
| CONTRIBUTING.md | Building, style, and where documentation goes |
This project was written with AI assistance. Design, review, testing and responsibility for every line are the maintainers'.
ghost is licensed under the GNU General Public License v3.0 only.
libgdp and the GDP specification are MIT, so other
clients and hosts can implement the protocol on any terms. Vendored
third-party files keep their own licenses. License coverage follows
REUSE; run reuse lint to check it.
