Repository navigation
Build the USB image
This is the default build. Download and unpack Valve's current SteamOS recovery image, then get the full repository: Get the repository below has the commands. Setup instructions follow after that. Windows users can start with Build on Windows, and Bazzite users with Build on Bazzite.
The complete builder prepares the disposable SteamOS environment and builds all four artifacts automatically. Run it from the repository root on your Linux build host:
sudo bash tools/build-complete.sh /absolute/path/to/recovery.imgUse the original recovery image Valve publishes, whichever release that currently
is. You do not need to prepare a chroot or call each artifact builder yourself.
The default includes MangoApp, the corrected Gamescope build with both the
capture color fix and the Game Mode menu fix, Remote Play receiver support,
NVENC, built-in controller support and the GitHub updater configured with this
project's public signing key. It selects the NVIDIA driver recorded in
config/build-baselines.json and requests compute-library trimming. See the
CUDA note below before using trimming in a custom streaming configuration.
The builder prints the recovery release it found. Releases this project has
validated are listed in config/build-baselines.json; anything else produces a
warning and the build continues. The check that does refuse is a build root whose
package repositories come from another SteamOS line, because the compiled
artifacts would then target libraries the image does not ship.
Allow at least 50 GiB free on the Linux work filesystem after downloading the
input. The script creates a new work directory next to it; choose another existing
parent with --workdir /path/to/new-build-directory. The directory itself must not
already exist. The output image and .sha256 file are written next to the input.
Existing output is refused, not overwritten.
The recovery root is mounted read-only; compilation changes go into a separate
OverlayFS layer. Package signatures remain enabled. On success, compilation
residue is removed after unmounting; artifact directories, driver cache and
build.log remain. On failure, the script stops, detaches its mounts and retains
the work directory for diagnosis. Do not flash incomplete output or remove a
work directory until mounts and loop devices have been checked.
For another trusted updater configuration, use --source /path/to/source.json.
The default public package's supported OS list is unchanged by this builder.
Run --help for driver selection and other options.
The complete wrapper has built an image from the original 3.8.14 recovery image in an Arch Linux QEMU guest on Windows. All four artifacts were compiled during that run. Read-only output checks passed for the driver, addon integrity, 32-bit/64-bit NVIDIA libraries and updater configuration, with xpadneo absent. The output checksum was generated by the wrapper. The tester subsequently confirmed installation, the OS update, controller operation and Remote Play in both directions. HEVC Video was enabled manually in Advanced Client Options; see Remote Play client settings. These results cover the tested setup, not every client or hardware configuration.
A small real Btrfs/OverlayFS fixture also checks failure cleanup, unchanged input hashes and refusal to overwrite an existing output. Build-root background agents are stopped before unmounting; unrelated host services are not stopped.
If the host check reports case-insensitive capable filesystem ... not supported,
the kernel cannot use that filesystem as the writable OverlayFS layer. Renaming
the folder does not change the filesystem feature. Do not disable casefold on
your existing home partition.
Create a separate ext4 filesystem inside a file and use it for the build work. Allow at least 100 GiB of actual free disk space before this example. The 80 GiB file is sparse: it grows as the builder writes data, so its apparent size does not reserve free space. Keep the original recovery image outside this file.
Run these commands in one terminal, from the unpacked repository directory:
build_area=$(mktemp -d "$HOME/steamos-build.XXXXXXXX")
truncate -s 80G "$build_area/work.img"
mkfs.ext4 -O ^casefold -m 0 "$build_area/work.img"
mkdir "$build_area/work"
sudo mount -o loop "$build_area/work.img" "$build_area/work"
sudo bash tools/build-complete.sh --workdir "$build_area/work/complete" /absolute/path/to/recovery.imgUse source release 0.1.3 or newer when checking out or exporting the source
on Windows. It enforces LF line endings for patches and VERSION regardless of
Git's autocrlf setting. Older Windows checkouts/exports can fail on patch
application or Invalid installer VERSION; ZIP archives downloaded directly
from GitHub are not affected by that Windows conversion.
The output image and checksum are next to the input recovery image. Once the builder has finished and detached its child mounts, unmount the workspace:
sudo umount "$build_area/work"Keep work.img if you want to retain logs, artifacts and the driver cache.
If unmount reports that it is busy, inspect remaining mounts and processes
before removing anything. Do not reformat or delete your home partition.
The casefold rejection and the file-backed ext4 workaround were tested on SteamOS kernel 6.16.12. A full complete build using this filesystem layout also passed in an Arch Linux VM. The VM test does not establish that every installed SteamOS system has all required build dependencies; the host check still applies.
A user also completed the full build on an installed SteamOS system using this workspace, then confirmed that the image booted after being written with Etcher and that changing the NVIDIA driver worked. This does not confirm an OS update or every hardware configuration.
Download and extract Source code (zip) or Source code (tar.gz) from Releases and keep the whole archive, or clone the repository on Linux:
git clone https://github.com/60plus/steamos-nvidia-installer.git
cd steamos-nvidia-installerKeep the full checkout. The main script needs the files in lib and
scripts. The three installer-* assets on the Releases page are for
Installer Update, not source archives and not bootable images.
Get the image through Valve's recovery instructions.
Unpack the archive to obtain an .img file. Use the recovery/repair image, not
an image of an already installed system. Replace the example paths below with yours.
The basic command below builds NVIDIA support and the standard installer helpers. It does not compile or add the corrected overlay, the corrected Gamescope, the Remote Play artifacts, the NVENC bridge or the desktop updater automatically. The corrected Gamescope is the part that repairs the corrupted Game Mode menus on NVIDIA, so an image built with the basic command alone does not carry that fix. That command also sets up no updater, so an installation made from such an image cannot be sent the fix later. You can include these components; to build the complete configuration, build the artifacts described below and supply all relevant options together.
sudo ./steamos-nvidia-installer.sh /path/to/recovery.imgThe script creates a copy ending in -nvidia-usbinstall.img. It keeps the original
image unchanged and prints the output path when finished. While the build runs the
file ends in -nvidia-usbinstall.partial.img instead, and it is renamed only when
the build has succeeded, so a file with the flashable name is always a finished
build.
An image from an earlier build is left alone until the new one succeeds. That means
that after a failed build, an -nvidia-usbinstall.img sitting next to your input is
the older image, not the one you just tried to make. Check the time on the file
before flashing it. The unfinished .partial.img is removed by the next run.
The default selects the driver recorded in config/build-baselines.json, which is
the version this project tests on hardware. To select a different build:
sudo ./steamos-nvidia-installer.sh --driver 610.57.04-1 --trim-cuda /path/to/recovery.img--driver latest resolves whatever Arch ships on the day you build. That is a
deliberate choice, not the default: the newest packaged driver has not been tested
by this project and has carried regressions in the past. Choose a driver compatible
with both your GPU and the image kernel. --trim-cuda removes CUDA, OpenCL and
OptiX libraries; omit it if your applications need them.
| Option | Purpose |
|---|---|
--driver SPEC |
Select a version prefix or an exact package version, or latest for the current Arch package. Default: the tested version in config/build-baselines.json. |
--installer-update-source FILE |
Include the desktop updater with a maintainer-supplied source and public signing key. |
--mangoapp-dir DIR |
Include the corrected performance overlay artifact. |
--gamescope-dir DIR |
Include the corrected Gamescope build: the capture color correction and the fix for corrupted Game Mode menus. Leaving it out leaves out both. |
--remote-play-dir DIR |
Include the SDR receiver and decoder color correction. |
--nvenc-dir DIR |
Include the 32-bit to 64-bit hardware-encoding bridge. |
--workdir DIR |
Choose a reusable build cache. |
--trim-cuda |
Reduce the driver payload by removing compute libraries. |
--xpadneo |
Add the optional Xbox Bluetooth driver. |
--no-xpadneo |
Use built-in controller support, the default. |
--xpadneo-version TAG |
Select an exact xpadneo tag; default v0.10.4. |
--experimental-preview |
Select Valve's Preview channel for a separate test installation. Self-healing mode only; cannot be combined with beta. |
--experimental-beta |
Select Valve's beta channel for first setup and OS updates. Experimental, self-healing mode only. |
--hold-updates |
Freeze OS updates; Steam reports the system as up to date. |
--no-hold-updates |
Use stock updates, which remove the added NVIDIA driver. |
--no-installer |
Produce a patched bootable image without desktop installation shortcuts. |
--skip-sigcheck |
Disable package signature checks during building. Avoid for normal use. |
--preflight |
Run the host checks and stop. Nothing is built and nothing is changed. |
The normal update mode repairs NVIDIA after OS updates. No extra flag is needed.
The older build-xpadneo.sh wrapper explicitly enables xpadneo and forwards other
options to the main script. Start without xpadneo unless your controller needs it.
When enabled, xpadneo also changes system-wide Bluetooth settings.
For package signature failures, check the clock, keyring and failing package before considering a bypass. See Troubleshooting.
For a base-only or manual build, use the included public configuration with
--installer-update-source config/github-stable.json. This enables
SteamOS NVIDIA Installer Update in the installed system.
It requires the normal self-healing update mode. Without this option, the desktop
updater is not included. Do not replace the source or signing key with one from
an untrusted download.
Use an image-writing tool to write the entire output image to the USB device.
Etcher has been confirmed to write a working installer USB. Select the completed
.img, choose the correct USB drive and let writing and verification finish.
If booting through Ventoy fails, write the image directly to the USB drive with
Etcher or the dd command printed by the builder. One reported setup failed
with Ventoy and booted after a direct write with Etcher; this is not a claim that
Ventoy fails on every setup.
Copying the file onto a formatted USB drive is not enough. Verify the destination by capacity and model; writing the image erases the USB.
On Linux, list devices with:
lsblk -o NAME,SIZE,MODEL,TRAN,MOUNTPOINTSWait for writing and verification to finish before removing the drive. You can
record the image checksum with sha256sum /path/to/output.img.
Continue with Install and first boot.
Maintainers can build the pinned MangoApp artifact with:
sudo bash tools/build-mangoapp.sh /path/to/disposable-steamos-root /path/to/new-mangoapp-outputUse a disposable SteamOS build root with /proc, /dev and DNS prepared. The
script installs build dependencies there. Do not pass an installed system or the
root filesystem of a running PC. The output directory must not already exist.
Use the same SteamOS library baseline as the target image.
Add --mangoapp-dir /path/to/new-mangoapp-output to the image build command.
The release packer accepts the same option for an integration update. Include all
three output files together: mangoapp, mangoapp-build.json and
MangoHud-LICENSE. See How it works.
Use --experimental-beta or --experimental-preview only for a separate test
installation. Choose one. The recovery image's original OS remains the
installation base; the selected channel supplies subsequent OS updates,
including first setup. These options do not copy individual experimental
packages into the older system. Valve's server chooses the downloaded version,
which can change after the image is built.
Keep a working stable installer and use a separate test disk. Neither option enables main or establishes compatibility with every future experimental build.
A Preview installation runs SteamOS's own Gamescope rather than this project's build. That is
deliberate. The build is matched to one exact Gamescope package on the SteamOS 3.8 line, and it
steps aside rather than put an older compositor on a newer system. Preview is the newer 3.9 line.
The capture color correction is a backport of a change Valve's newer Gamescope already contains,
so Remote Play colors from this machine are unaffected. What is not in Valve's build is this
project's own fix for the corrupted Game Mode menus, so that fix is not active on Preview. Nothing
on screen says so. The diagnostic report names the Gamescope selection, and on Preview it reads
stock. Applying a project release on the 3.9 line has not been tested, and it would not change
this selection.
An image built with all components in the build guide already includes the Gamescope, receiver and NVENC artifacts described below. These sections explain how to reproduce that build. The options are optional for custom builders; users of that image do not need to build or enable the fixes themselves.
The artifact carries two corrections. The first fixes the colors that a Remote
Play host and a screenshot capture produce on an NVIDIA GPU. The second stops
Gamescope handing a layer that needs alpha blending to a hardware plane on an
NVIDIA display, which is what corrupted the Game Mode menus. The second
correction switches itself on only for a display the kernel reports as
nvidia-drm, and GAMESCOPE_NVIDIA_COMPOSITE_ALPHA=0 turns it off again if you
need to compare.
Use a disposable stable SteamOS build root with /proc, /dev, /sys and DNS
available. The tool reinstalls build dependencies there because recovery images
remove development headers while retaining their package database entries. Never use /
or the installed system you are testing as the build root.
sudo bash tools/build-gamescope.sh /path/to/disposable-steamos-root /path/to/new-gamescope-outputThe output directory must not exist. The tool stages files under root/ and
records provenance in gamescope-build.json. It does not install them into the
running system. Keep the license files with the artifact. Compilation and pixel
conversion checks do not replace a physical Remote Play and screenshot test.
To include the artifact in an installer, add --gamescope-dir /path/to/new-gamescope-output to
the normal image build command. The release packer accepts --gamescope-dir as well, so an
integration update can deliver a new Gamescope build to a system that is already installed, with
no new USB image. That reaches a system whose installed release is 0.1.9 or newer, because an
update writes only the files the installed copy of the update tool already knows about, and
Gamescope joined that list in 0.1.9. The recovery desktop keeps its original Gamescope. The
corrected build is activated once the installed system ships the Gamescope package the artifact
was built from, on the SteamOS 3.8 line. An image may carry the artifact on any channel; the
selection happens at install and repair time and returns to Valve's build whenever the package
does not match.
Build the decoder and receiver environment helper in a disposable stable SteamOS 3.8 build root, then pass the artifact directory to the installer:
sudo bash tools/build-remote-play.sh /path/to/build-root /path/to/remote-play-artifact
sudo ./steamos-nvidia-installer.sh --remote-play-dir /path/to/remote-play-artifact /path/to/recovery.imgThe artifact includes source revision, patch hashes, binary hashes and the decoder
license. It adds SDR receiving support without replacing files inside Steam's
user installation. Combine it with --gamescope-dir to include the corrected
Gamescope build, which carries the sending-side capture correction. Test both
directions after installation and again after the first SteamOS update. The
receiver policy uses SDR; HDR receiving is not provided by this configuration.
Build the pinned encoding driver and helper in the same kind of disposable stable SteamOS root used for the receiver build:
sudo bash tools/build-nvenc.sh /path/to/build-root /path/to/nvenc-artifact
sudo ./steamos-nvidia-installer.sh --nvenc-dir /path/to/nvenc-artifact /path/to/recovery.imgThe builder records the source revision and file hashes and includes the upstream license. The bridge is optional. Combine it with the capture and receiver artifacts when testing Remote Play in both directions. It installs a 32-bit VAAPI encoding driver and a 64-bit user service. It does not replace the private receiver decoder. Test streaming, reconnect, reboot, suspend and the first OS update before distributing an image. Hardware tests of a separately installed prototype do not validate a new image.
Release downloads do not contain Valve's recovery image or a complete SteamOS image. Obtain the recovery image directly from Valve using the link above. The commands below combine all of this project's integration components.
First prepare a disposable, writable SteamOS 3.8 build root on a Linux filesystem.
It must contain the system's /etc, /usr and package database, have working
package repositories and DNS, and have /proc, /dev and /sys mounted inside it.
Use a copy for building, never your running installation or your only recovery image.
Do not substitute an ordinary Arch root: the resulting binaries need the target
SteamOS library versions.
tools/prepare-build-root.sh creates one from an unpacked recovery image. It is
the same code the complete build uses, so the two cannot drift apart:
sudo bash tools/prepare-build-root.sh /path/to/recovery.img /path/to/new-workdirIt mounts the image read only, stacks a writable overlay on it, mounts /proc,
/dev and /sys, gives the chroot a working resolver, initializes a private
package keyring and syncs the databases. It prints the path of the prepared root.
Preparing a work directory that already holds an upper layer keeps the packages installed last time, which turns a repeated artifact build from an hour into minutes. When you are finished with it:
sudo bash tools/prepare-build-root.sh --cleanup /path/to/new-workdirThat unmounts everything and detaches the loop device while keeping the upper layer for the next rebuild.
From the repository root, replace the two absolute paths below. Keep each output directory new; artifact builders refuse to overwrite existing outputs.
build_root=/absolute/path/to/disposable-steamos-root
artifacts=/absolute/path/to/new-artifacts
mkdir -p "$artifacts"
sudo bash tools/build-mangoapp.sh "$build_root" "$artifacts/mangoapp"
sudo bash tools/build-gamescope.sh "$build_root" "$artifacts/gamescope"
sudo bash tools/build-remote-play.sh "$build_root" "$artifacts/remote-play"
sudo bash tools/build-nvenc.sh "$build_root" "$artifacts/nvenc"
sudo ./steamos-nvidia-installer.sh \
--driver 610.57.04-1 --trim-cuda \
--mangoapp-dir "$artifacts/mangoapp" \
--gamescope-dir "$artifacts/gamescope" \
--remote-play-dir "$artifacts/remote-play" \
--nvenc-dir "$artifacts/nvenc" \
--installer-update-source config/github-stable.json \
/absolute/path/to/recovery.imgThe pinned configuration uses a SteamOS 3.8.14 recovery image and the normal
stable update path to 3.8.16. It does not import a beta kernel. Check the image's
reported version before building; a different recovery or target OS version
requires fresh compatibility testing. Omit --trim-cuda if you need compute libraries.
Keep the artifact metadata and license files together with each artifact. After a successful build, calculate the output checksum, write the image to USB and test installation, the first OS update, suspend/resume, the overlay and both Remote Play directions. Successful compilation alone does not verify those functions.
--trim-cuda filters CUDA, OpenCL, NVVM and OptiX paths from the main builder's
payload list. It is not a switch to disable Remote Play or NVENC. However, the
project's 64-bit NVENC helper dynamically loads libcuda.so.1, so removing that
runtime library can prevent hardware encoding. A normal loader dependency check
does not cover all libraries loaded dynamically at runtime.
Inspection of the complete test image confirmed that matching libcuda,
libnvidia-encode and libnvcuvid libraries are present despite trimming being
requested. Do not interpret the flag as proof that the final image contains no
CUDA runtime, or assume every streaming implementation works without it.
Use --keep-cuda with the complete builder, or omit --trim-cuda with the base
builder, when retaining compute libraries. Validate both Remote Play directions
after installation and OS updates.
Start here
Build the installer
Install and run
When something is wrong
Under the bonnet