Install
Get a working scoot binary. Pick your build first (one command), then
your path below — or take the whole desktop and
skip choosing piece by piece.
Which build do I need?
Section titled “Which build do I need?”Two axes, decided independently: CPU or GPU rendering, and whether you need X11 apps. Four prebuilt packages cover the combinations (all in the Cachix cache, below):
| Package | Renders with | Needs | Pick it when |
|---|---|---|---|
scoot (default) |
pixman on the CPU; no GPU at all | nothing | VM, webtop/container, no /dev/dri, nested-only use, or unsure |
scoot-gpu |
GPU scanout under --tty, dma-buf handoff under --nested |
a DRM render node + Mesa/GBM driver, and a real seat for --tty |
daily-driving on real hardware (laptop/desktop, Intel/AMD/Apple Silicon) |
scoot-xwayland |
as scoot |
as scoot, plus X11 apps to run |
you need X apps but no GPU path |
scoot-gpu-xwayland |
as scoot-gpu |
as scoot-gpu, plus X11 apps to run |
real hardware and X apps |
XWayland is its own axis for a reason: it adds ~344 MiB of closure (all but ~12 MiB of it Xwayland’s own, which links Mesa) and a trust decision — any X client can keylog and read other X clients by design. Take it only if you run X apps. (More in XWayland.)
One visible side effect of the two -xwayland packages: their wrapper
leaves the process name as .scoot-wrapped, not scoot — so pgrep -x scoot finds nothing there; use pgrep -x .scoot-wrapped.
The one-command check
Section titled “The one-command check”ls /dev/dri/renderD*- No output (no such directory, no matches) → there is no GPU to use.
Take the default
scoot. This is the VM, webtop and container case, and it is a first-class configuration, not a degraded one: pixman is the default renderer and GPU-free operation is a hard requirement, not a fallback tier. - A render node listed (e.g.
renderD128) → a GPU exists. On real hardware with Intel/AMD graphics or Apple Silicon under Asahi Linux, takescoot-gpu. On a VM the node is usually software (llvmpipe) — thereglesis several times slower than pixman, so stay on the default unless you measured otherwise.
Confirm what you actually got from scoot’s own startup log: with
--renderer gles a working GPU prints the GLES renderer is up
with device=/dev/dri/renderD128 software=false. Trust that line over
the flag name — a device node backed by a software driver answers
software=true, and then you are rendering in software anyway.
What the GPU build buys, measured on an Apple M2 under Asahi Linux:
4–5x less compositor CPU under damage (20.8% of a core → 4.3% under
large-damage pointer motion; 52.0% → 14.0% under a full relayout), the
same pixels, ~0.2 W less power, 7–16 MB more RSS, and no measurable CPU
difference at idle. What it costs: the EGL drivers must come from your
system (NixOS: hardware.graphics enabled), and --tty scanout needs
the real seat.
Symptom:
--renderer glesexits at startup naming EGL devices. That is the intended behavior, not a bug to work around: when EGL itself is missing or broken, a wrong--renderer glesis a startup error, never a silent downgrade — scoot names each failure and points back at--renderer pixman, which needs no GPU at all. There is no automatic fallback to the CPU tier on that path. Either drop the flag (stay on pixman) or fix the cause: the GPU build installed, drivers present, render node visible. (The one deliberate fallback is the other direction: under--tty, aglessession whose device cannot drive GPU scanout warns and keeps the CPU renderer with dumb buffers instead of refusing to start — see Backends and rendering.)
Say it in the config
Section titled “Say it in the config”The package knob is programs.scoot.package (home-manager and NixOS
alike; the desktop profile never sets it — the choice stays yours):
programs.scoot = { enable = true; # Real hardware with a GPU: take the scanout build. package = inputs.scoot.packages.${pkgs.system}.scoot-gpu; # ...plus X11 apps? Use scoot-gpu-xwayland instead.};Leave the default (omit package) for the CPU build. The same names
work with nix profile add and nix run below — swap scoot for
scoot-gpu (or a -xwayland variant) wherever it appears.
Try it without installing
Section titled “Try it without installing”If you have Nix, run scoot straight from the flake. Nothing is installed:
nix run github:scoot-sh/scoot -- --nested -- footThis opens scoot in a window on your current desktop with a terminal in it.
Close the window to quit. (Why foot? It is scoot’s default terminal —
install it too, or name another one. More in First session.)
Install with Nix
Section titled “Install with Nix”scoot runs on Linux. With Nix:
nix profile add github:scoot-sh/scoot#scoot github:scoot-sh/scoot#scootctl \ github:scoot-sh/scoot#scootbarSymptom:
nix: command 'nix' not found, or your Nix saysnix profile installinstead ofnix profile add. Older Nix calls the subcommandinstall— same command, old name. If Nix itself is missing, install it from nixos.org first.
Skip the compile: the binary cache
Section titled “Skip the compile: the binary cache”Every merge to main pushes built binaries for x86_64-linux and
aarch64-linux to the public Cachix cache scoot-sh — all four scoot
variants above, plus scootctl, scootbar and scootbg. Without it, Nix
compiles Smithay and scoot’s crates on your machine (minutes); with it, you
download. Opt in explicitly in your Nix configuration — NixOS
(configuration.nix):
nix.settings = { extra-substituters = [ "https://scoot-sh.cachix.org" ]; extra-trusted-public-keys = [ "scoot-sh.cachix.org-1:QMj7CMw8uqZxrvqqm6SggdxTHz6Q4prt30ydDcXJXCo=" ];};Per user (~/.config/nix/nix.conf), the same two lines:
extra-substituters = https://scoot-sh.cachix.orgextra-trusted-public-keys = scoot-sh.cachix.org-1:QMj7CMw8uqZxrvqqm6SggdxTHz6Q4prt30ydDcXJXCo=What this trusts: binaries built by CI from reviewed merges to main. A
substituter can serve any store path your Nix asks for, so this trusts CI’s
builds the way installing the flake already trusts its source.
Packaging notes
Section titled “Packaging notes”The names in the chooser above are flake outputs
(packages.<system>.*); the same derivations are also pkgs.*
through the overlay, nix run apps, and per-system defaults:
| Name | Gives you | Pick it when |
|---|---|---|
scoot |
the compositor alone ($out/bin carries only scoot) |
the Linux default; VM, webtop, nested-only |
scoot-gpu |
the same binary with the gpu-scanout feature |
real hardware with a GPU (still named scoot) |
scoot-xwayland / scoot-gpu-xwayland |
those two with the xwayland feature and Xwayland on PATH (Linux only) |
you run X11 apps |
scootctl |
the standalone remote-control client (every system) | driving a compositor running in a VM |
scootbg |
the wallpaper daemon (Linux only) | [wallpaper] without the desktop profile |
scootbar |
the status bar, no font in its closure (Linux only) | the bar with your own fonts |
scootbar-demo |
the bar with a nixpkgs font as its default | trying the bar on a box with no fonts |
default |
scoot on Linux, scootctl on macOS — whichever is honest there |
nix run without choosing |
nix run mirrors six of them — default, scootctl, scoot-gpu,
scoot-xwayland, scootbar and scootbar-demo (no scootbg,
scoot-gpu-xwayland or docs-site app):
nix run github:scoot-sh/scoot -- --nested -- footnix run github:scoot-sh/scoot#scootbar-demo -- daemon --right clockThe overlay
Section titled “The overlay”overlays.default adds pkgs.scoot, pkgs.scootctl and, on Linux,
pkgs.scootbg and pkgs.scootbar:
nixpkgs.overlays = [ inputs.scoot.overlays.default ];They are the flake’s own builds, the same derivations as
packages.<system>.*, not rebuilt against your nixpkgs — nothing is
built twice. With the overlay applied, the modules’ package and
wallpaper.package default to these, which is what makes the pure
modules usable without the flake’s wrappers. On macOS the overlay adds
scoot and scootctl (the client) and no scootbg or scootbar. It
never adds scootbar-demo: a demo to run, not a package to build on.
Per-side macOS split, same rule everywhere: the home-manager module
manages the config file on any system (on macOS files-only, with
package defaulting to null — the config you edit here deploys to a
Linux box), while the NixOS module’s session entry only means anything
on NixOS. scootbg and scootbar are Linux-only: no macOS package,
and on macOS a [wallpaper] section renders as written and installs
nothing.
Symptom: converting an old
flexwmsetup builds fine but the session boots on built-in defaults — scale and binds silently gone — or the login entry fails. Three renames, all silent at build time (Nix interpolates store paths without checking the binary exists):${pkg}/bin/flexwm→${pkg}/bin/scootin wrappers andExec=lines;xdg.configFile."flexwm/config.toml"→programs.scoot.settings(or"scoot/config.toml") — this is the dangerous one, so move the content and delete the old entry, otherwise your real config sits orphaned at a path nothing reads; and the module split (homeModules.scoot, with the legacyhomeManagerModules.scootspelling still resolving, owns the config file,nixosModules.scootowns the binaries and the login entry — a hand-rolledxdg.configFilenext to the module manages a file scoot never reads, so keep the module’s and delete the hand-rolled one).
Symptom: rebuild fails with
not of type 'TOML value'namingprograms.scoot.settings. A value with no TOML representation (a Nix function insettings) fails the option type-check at evaluation time — loud and early, before anything builds, let alone starts a session. A value that renders but has the wrong scoot type (a string forlayout.gap) builds fine and is refused at session start instead, where the loader fails safe — see Failure semantics.
Build from source
Section titled “Build from source”On Debian or Ubuntu (Rust 1.87 or newer):
sudo apt install pkg-config libwayland-dev libxkbcommon-dev libinput-dev \ libdrm-dev libdisplay-info-dev libseat-dev libudev-dev libpixman-1-dev \ libgbm-dev libegl-dev libdbus-1-devgit clone https://github.com/scoot-sh/scoot && cd scootcargo build --release -p scoot -p scootctl -p scootbarThe binaries land in target/release/. For the GPU build, add the
feature: cargo build --release -p scoot --features gpu-scanout (plus
xwayland for X apps).
Check it worked
Section titled “Check it worked”scoot --helpThis prints the usage text and exits — no display needed. If it complains
about a missing library, re-check the apt line above; if it says
something about --headless on macOS, that is expected: on a Mac only the
scootctl remote-control client builds.
Next: First session — run scoot, open a terminal, learn five keys. Or skip the piece-by-piece path: the scoot desktop is one switch plus a look.