Run a Slipstream host on SteamOS, stream its Game Mode (or desktop) to your other devices. One script, built on-device and ABI-matched to SteamOS.
This is for using a SteamOS device as the host, streaming from it to a laptop, TV, phone, or
another device. (For the usual case, streaming to a Steam Deck, see Install a Client,
which uses the Flatpak + Decky plugin.)
We support SteamOS as a host mainly with an eye to the upcoming Steam Machine, a living-room,
desktop-class SteamOS box is a natural always-on streaming host. The Steam Deck is the SteamOS
device we can test on today, so it's what these instructions are validated against; the same
on-device build works on any SteamOS 3 system.
New here? Read Security & Safe Use first, a streaming host is remote control of
the machine, so keep it on a trusted LAN or VPN and require pairing.
SteamOS is an immutable, read-only Arch base, so the host isn't a system package. Instead a single
script builds the host natively inside a Debian-trixie distrobox (ABI-matched to SteamOS's
FFmpeg/glibc, the binary then runs natively on SteamOS) and wires it up as systemd user services.
Building on-device means a rebuild always matches the running OS, so a SteamOS update can't leave you
with a binary linked against the wrong libraries. Encode is auto-detected: Vulkan Video on the
Deck's AMD GPU (with libav VAAPI as the fallback), NVENC on NVIDIA. The installer writes
RADV_PERFTEST=video_encode into ~/.config/slipstream/host.env, Van Gogh's RADV driver hides
Vulkan encode behind that flag, and without it sessions quietly fall back to VAAPI. Set
SLIPSTREAM_VULKAN_ENCODE=0 in host.env to force the libav VAAPI path.
Heads up: in our testing the Steam Deck's WiFi tx topped out around ~250 Mbps of goodput
regardless of band, enough for 1080p/1440p60, not 4K. This looked like a hardware/driver
packet-rate limit rather than a bandwidth ceiling, but it's one device measured on one network:
other SteamOS hardware, newer drivers, or a less congested band may do better. A wired dock
sidesteps it entirely. See Configuration for bitrate guidance.
A SteamOS device on SteamOS 3 (e.g. a Steam Deck, LCD or OLED). Steady WiFi or, better, a wired dock.
A sudo password. A stock SteamOS deck account has none at all, so sudo can't work
until you set one. Do it once, before you start:
passwd
Without it the installer runs, but skips every root step: gamepad passthrough, vhci-hcd, the
UDP buffer tuning, the atomic-update keep list and linger.
Run the installer on a real terminal, Konsole in Desktop Mode, or ssh -t. A
non-interactive ssh session has no TTY for the sudo prompt, and the same steps get skipped.
distrobox installed (no root needed). If distrobox isn't found:
curl -sfL https://raw.githubusercontent.com/89luca89/distrobox/main/install | sh -s -- --prefix ~/.local
Make sure ~/.local/bin is on your PATH (re-open the terminal).
The first build downloads a container image + toolchain (~1 GB) and takes ~10-15 minutes, then
another ~5-10 minutes for the HDR gamescope build (a second set of dependencies plus a fresh
gamescope clone). Budget around 25 minutes for a first install. Later rebuilds are incremental,
and the gamescope step is a no-op unless its sources changed.
creates the pf2 Debian-trixie distrobox and installs the build toolchain,
builds slipstream-host, the web console, and the plugin/script runner (so the console's
plugin store works out of the box, the runner service itself stays opt-in),
writes config to ~/.config/slipstream/ (a generated web-console login password),
raises the UDP socket buffers to 32 MB, installs the gamepad udev rule + the vhci-hcd autoload
and adds you to the input group (virtual gamepads / native Steam Deck controller passthrough),
seeds the KDE RemoteDesktop grant for Desktop-mode input, and registers all of it on SteamOS's
atomic-update keep list so OS updates carry it over, the installer asks for your sudo
password first, before the long build, so you can authorise once and walk away,
installs + starts the slipstream-host and slipstream-websystemd user services (with linger,
so they run without a login session) plus a boot-time rebuild check that repairs the host
automatically if a SteamOS update ever breaks its library links.
Useful flags:
Flag
Effect
--open
Accept unpaired clients (trust-on-first-use), convenient on a fully trusted LAN. Default is PIN pairing required.
--no-gamestream
Run a secure native-only host, skip the GameStream/Moonlight-compat planes (see below). Default keeps them on so stock Moonlight works.
--no-web
Skip the management web console.
--src=DIR
Build from source at DIR instead of ~/slipstream. Only if you must, the post-OS-update rebuild check and the web console's one-click update both look for ~/slipstream/scripts/steamdeck/update.sh, so with a relocated source you have to update by hand: SLIPSTREAM_SRC=DIR bash DIR/scripts/steamdeck/update.sh --pull (without SLIPSTREAM_SRC the script still looks for ~/slipstream). A symlink (ln -s DIR ~/slipstream) restores both.
When it finishes it prints the web-console URL and how to pair.
GameStream/Moonlight compat is on by default. The native slipstream/1 plane (used by
Slipstream's own clients, SPAKE2 PIN pairing, per-direction AEAD) is always on and is the secure
path. The installer also enables the GameStream/Moonlight-compat planes so stock
Moonlight works, but those carry inherent on-path weaknesses (pairing over plain
HTTP; legacy control encryption that can reuse GCM nonces), so enable them only on a trusted LAN.
If you only ever use native clients, install with --no-gamestream for a host with no GameStream
surface at all.
First install, reboot once before streaming. KWin only authorizes Desktop-mode screen capture
on a fresh session, and the new input group (native Steam Deck controller passthrough) only takes
effect on a new login, so after the first install, reboot the Deck (a re-run that changes
nothing doesn't need it). Streaming Game Mode with a generic Xbox pad works right away; Desktop
capture and the native Steam Deck controller need the reboot. If a client connects and every
session ends with KWin does not expose zkde_screencast_unstable_v1 or the pad shows up as an Xbox
360 controller, you haven't rebooted yet.
By default the host requires PIN pairing (secure). Two ways to pair:
Web console (printed at the end of step 2): open https://<device-ip>:47992 (self-signed host
cert, your browser warns once; trust it and continue),
arm pairing, and enter the PIN on your client.
From the client directly: pick this host (it advertises over mDNS as _slipstream._udp) and
enter the PIN the host shows.
On a trusted home LAN you can instead install with --open and skip pairing entirely.
The installer generates a random console login password (printed at the end of step 2) and writes it
to ~/.config/slipstream/web.env. To read it back or set your own, see
The Web Console.
systemctl --user status slipstream-host # active (running)journalctl --user -u slipstream-host -f # watch a client connect
Connect from a native client, or from Moonlight (unless you
installed with --no-gamestream). In Game Mode the host attaches to the running gamescope session and
streams it at your client's resolution; in Desktop Mode it streams the KDE desktop. The host
auto-detects which session is live per connection. See Steam / gamescope for the
attach-vs-managed detail and known limits.
The installer also builds slipstream-gamescope, gamescope plus the small patch that adds the
10-bit PQ formats to its capture node (see HDR on gamescope),
and points the host at it. Nothing to configure: with it in place, a 10-bit-capable client with
HDR enabled streams true HDR10 from Game Mode; anything missing and the session streams 8-bit SDR
instead (never a mislabelled picture). Check what the host resolved with:
( set -a; . ~/.config/slipstream/host.env; set +a ~/slipstream/target-steamos/release/slipstream-host hdr-probe )
Run it exactly like this, the probe reads its answers from the environment, and host.env is what
the service runs with (including which gamescope the host uses). A bare shell doesn't have it, so
the probe would describe an environment your host never runs in.
The build is best-effort: if it fails, the installer says so loudly and everything else keeps
working in SDR, re-run update.sh to retry. SLIPSTREAM_GAMESCOPE_HDR=0 in
~/.config/slipstream/host.env forces SDR deliberately.
From the web console (easiest). The Updates card shows an Update now button, no opt-in and
no root, because this install is owned by your own user. It asks for the console password, then
rebuilds on the device, so expect several minutes; the card shows progress and the full log lands in
~/.config/slipstream/logs/update-steamos.log. See Updating.
From a terminal. One command, --pull fetches the new source first:
Drop --pull if you rsync source in yourself. update.sh also retrofits anything a newer installer
adds, the plugin runner, the HDR gamescope, the atomic-update keep list, the rebuild check, onto an
older install.
This install follows the canary channel. An on-device source build tracks main, not stable
vX.Y.Z releases, so the console offers you the newest main build. See
Release Channels.
Because this is a source build, "roll back" means "check out an older commit and rebuild":
git -C ~/slipstream checkout v0.22.3 # any release tagbash ~/slipstream/scripts/steamdeck/update.sh
That leaves the checkout on a detached tag, where git pull has no branch to fast-forward, so a
later update.sh --pull, and the console's Update now button (which runs exactly that), stops
with "You are not currently on a branch." Run git -C ~/slipstream checkout main first when you
want to follow main again.
There is no uninstall script, the install is spread across your user session and a few root-owned
files, so remove it in that order. Stop and forget the services first:
systemctl --user disable --now slipstream-host slipstream-web \ slipstream-scripting slipstream-rebuild-checkrm -f ~/.config/systemd/user/slipstream-*.servicesystemctl --user daemon-reloadsudo loginctl disable-linger "$USER" # only if nothing else on this device needs linger
Then the build container and everything the installer put under your home:
distrobox rm -f pf2 # the build container (~1 GB)rm -f ~/.local/bin/slipstream-scripting ~/.local/bin/slipstream-gamescoperm -rf ~/.local/lib/slipstream-scripting ~/.local/share/slipstream-scriptingrm -f ~/.local/share/slipstream/gamescope.stamprm -f ~/.local/share/applications/io.slipstream.Host.desktoprm -rf ~/slipstream # the source checkout and its target-steamos build dir
The build container shares your real home directory, so the toolchains it installed are in there
too: ~/.cargo, ~/.rustup and ~/.bun (plus the cargo download cache). Delete those only if
nothing else of yours uses Rust or bun.
Then the root-owned tuning. Don't skip this: the keep-list entry is what carries the other three
files through every SteamOS update, so left alone they stay on the device indefinitely.
Two things are deliberately left alone. ~/.config/slipstream/ holds your identity certificate,
paired devices and the console password, delete it only if you're not coming back:
rm -rf ~/.config/slipstream
And the installer may have seeded a KDE RemoteDesktop portal grant at
~/.local/share/flatpak/db/kde-authorized (only if you had none); remove that file if nothing
else on the device relies on it. Your input group membership is harmless to keep, drop it with
sudo gpasswd -d "$USER" input if you'd rather not.
See Uninstalling for the other install methods and what each one leaves behind.
Single session at a time at custom resolutions, two clients requesting different modes will
thrash the managed session. Pick one mode per session.
Keep the device awake. On handhelds, Game Mode auto-suspends on idle, which drops the host off
the network mid stream, disable auto-suspend (Settings -> Power) for a headless host.
Native Steam Deck controller passthrough presents the client's pad as a real Steam Deck
controller (paddles, trackpads, gyro) via a virtual USB device, that needs the input group and the
vhci-hcd module live, so it only works after the first-install reboot above; until then the pad
degrades to a generic Xbox 360 controller (still fully playable). If you're streaming to another
Steam Deck, also set Steam Input to Off for Slipstream on that Deck, see
Stream to a Steam Deck.
It survives OS updates, automatically. SteamOS A/B updates rebuild /etc and can move
library versions; the installer defends both sides. The system tuning (gamepad udev rule,
vhci-hcd, UDP buffers) is registered on SteamOS's own atomic-update keep list
(/etc/atomic-update.conf.d/), so updates carry it over; and a boot-time check
(slipstream-rebuild-check) probes the host binary and re-runs the build only if the new OS
actually broke its library links, you should never need to intervene. (Re-running update.sh
by hand still works and is harmless.)