Documentation
ujust commands — every Margine recipe
On an atomic system you don't hand-edit the OS — you run small, repeatable recipes. Margine ships its opinionated actions as `ujust` commands (Universal Blue's wrapper around the `just` task runner). Each one is idempotent, documents itself, and does exactly one job. This page is the full reference for Margine's own recipes: what each does, how to use it well, and the caveats (does it need sudo? a reboot? does it layer packages?). Type `ujust` on its own for the interactive menu, or `ujust --list` to see every recipe with a one-line description.
How to find them
ujust— opens the interactive menu (arrow keys + Enter).ujust --list— prints every recipe grouped by category, each with the one-line help shown below.ujust <name> <args>— runs one directly, e.g.ujust margine-scheduler lavd.
Most recipes take an optional argument; where one does, the default is shown in brackets. Margine's recipes are listed below by theme. (Bluefin/Universal Blue's base image also ships many ujust recipes — those show up in ujust --list too; this page covers only Margine's own.)
Setup & maintenance
The four you'll use most — bring the desktop to its intended state, update safely, and check health.
ujust margine-bootstrap [interactive]
Applies the full Margine user-state in one shot: home layout (~/data + ~/dev + ~/scratch + XDG remap + bookmarks), Hyprland-style keybindings, GNOME appearance, default apps (Zen, Ptyxis), and the Activities app-folder grouping. Runs every margine-configure-* step and prints a pass/fail summary.
- Why: gets a fresh login (or a drifted session after upgrades) to the complete intended state without running each step by hand.
- Best: it's idempotent — re-run it any time keybindings, bookmarks, or appearance drift; matching keys report
[no change]. Passunattendedto skip the confirmation prompt (this is what runs automatically on first login). Afterwards, log out/in (or Alt+F2 →r) to refresh the dock and bindings. - No sudo, no reboot, no package changes — pure user-state under
$HOME, reversible by hand.
ujust margine-update
Pulls the latest Margine :stable and stages it for the next reboot, automatically choosing the right upgrader: rpm-ostree upgrade if you have layered packages (e.g. native gaming), otherwise bootc upgrade.
- Why: it's the single correct way to update.
bootc upgraderefuses a layered deployment; this recipe always picks the one that works (and re-applies your layers). - Best: always use this instead of raw
bootc upgrade, especially aftermargine-gaming-native. It printsmargine-statusfirst so you see how far behind you are, then reboot withsystemctl rebootto switch in. - Needs sudo; the update is staged, not live (reboot required).
ujust margine-status
Read-only report: your deployment vs the latest published :stable, the Fedora → Bluefin → Margine lineage, and the running kernel. No sudo, changes nothing. Run it before deciding to update (margine-update calls it for you).
ujust margine-doctor
Runs every Margine validator in sequence with a one-line PASS/FAIL each — the "is my system as shipped?" health check. On a FAIL it points you at a per-run log under /tmp. It deliberately exits with an error if zero validators are found (that would itself be an image regression), so a clean run really means the checks ran.
Performance & input
ujust margine-scheduler [status|off|<scheduler>]
Switches the CPU scheduler (sched_ext / BPF) at runtime. No argument (or status) shows the current scheduler and the list of available ones; off stops scx_loader and returns to the kernel default (BORE); a name from the list (e.g. lavd) applies it and saves it as the boot default.
- Why: opt into a latency/throughput-tuned BPF scheduler. The schedulers ship in the image but stay off by default.
- Best: run
ujust margine-schedulerfirst to see the valid names for your kernel (they come straight fromscxctl list— an unknown name is rejected with the list reprinted, so you never guess). The GUI equivalent is Activities → Margine CPU Scheduler. - Applying/
offself-escalate via sudo; status needs none. Live, no reboot.
ujust wsf-preload [on|off|status]
Toggles the wayland-scroll-factor preload that Margine injects into GNOME Shell (on by default). off installs a systemd user drop-in that unsets it; on removes it; status reports the state.
- Best:
off/ononly take effect after a logout/login (the preload loads at shell start). To change scroll speed without logging out, runwsf set 1.0(or another factor) live instead. on/offuse sudo (system-level drop-in); status is read-only.
ujust margine-grub-hidpi
Forces the HiDPI GRUB font + grub.cfg re-render right now. You normally never need this — a boot service applies it automatically whenever the image's GRUB config changes. Run it only to apply the change immediately after an update instead of waiting for the next reboot. Needs sudo; idempotent and backed up (safe to re-run).
Gaming
Two flavours of the same layer — pick by how much you game. Both prompt before doing anything, both roll back, both need a reboot to activate their RPMs.
ujust margine-gaming
The default, Flatpak-first layer: Steam, Lutris, Heroic, Bottles, Protontricks, ProtonPlus and RetroArch as Flatpaks, plus gamescope + vkBasalt as the only rpm-ostree-layered RPMs.
- Why: the supported way to game on Margine (the separate Gaming image was retired). Sandboxed Flatpaks mean near-zero upgrade overhead — ideal for the occasional gamer.
- Best: the Flatpaks work immediately from Activities, but you must reboot to activate gamescope/vkBasalt. For host MangoHud inside Flatpak Steam:
flatpak override --user --filesystem=xdg-config/MangoHud:ro com.valvesoftware.Steam, thenMANGOHUD=1 %command%(andgamescope -- %command%) in a game's launch options. - Needs sudo; layers via rpm-ostree → from then on update with
ujust margine-update, neverbootc upgrade. Roll back withmargine-gaming-remove.
ujust margine-gaming-native
The native-RPM variant: Steam, Lutris and RetroArch as layered RPMs (Heroic/Bottles/Protontricks/ProtonPlus stay Flatpak).
- Why: maximum Proton/Wine compatibility — anti-cheat (EAC/BattlEye) works, VR/Steam Link/USB controllers integrate cleanly, Mesa always matches the system. The cost is +30–60s per update.
- Best: choose this if you game daily, run anti-cheat titles, or use VR; otherwise the Flatpak default is plenty. If you already ran the Flatpak variant, run
margine-gaming-removefirst. Reboot to activate the RPMs.
ujust margine-gaming-remove / ujust margine-gaming-native-remove
Roll back the respective variant (uninstall the gaming Flatpaks + un-layer the RPMs). Reboot afterwards to release the layer. Both keep the base-Margine helpers (mangohud, goverlay, gamemode, steam-devices, input-remapper, tuned…) since those are useful outside gaming too.
Security & disk
ujust margine-tpm-unlock [status|enable|disable] [7]
Manages TPM2 auto-unlock for the encrypted root. status inspects; enable [PCRS] enrolls the TPM2 and wires tpm2-device=auto into /etc/crypttab; disable removes only the TPM2 keyslot + its crypttab option. PCRs default to 7 (binds unlocking to the Secure Boot state).
- Why: the disk unlocks automatically from the TPM at boot — no passphrase prompt — while your LUKS passphrase stays as a fallback.
- Best: enable it after Secure Boot is on (PCR 7 measures it). Run
statusfirst, thenenable, then reboot to confirm a prompt-free unlock. It's lockout-proof by design: it refuses to leave the TPM as the only key. - Runs under sudo (all actions). Changes take effect at the next boot.
The old
ujust margine-tpm2-enrollis a deprecated alias kept for muscle memory (enroll→enable,remove→disable). Usemargine-tpm-unlockfor new work.
ujust margine-autologin [status|on|off] [user]
Enables/disables GDM autologin. status (read-only, no sudo) reports the config; on [user] enables it (backs up /etc/gdm/custom.conf and self-escalates); off disables it.
- Best: only enable this on a LUKS-encrypted machine — autologin boots straight to the desktop with no password, so disk encryption is what's still gating access at power-on. Pairs naturally with
margine-keyring.
ujust margine-keyring [status|blank|restore]
Fixes the login-keyring password prompt that appears under fingerprint login or autologin (PAM never gets the password that encrypts the keyring). status reports whether it's password-protected; blank backs it up and sets the password empty so it auto-unlocks; restore reverts.
- Best: run
statusfirst; useblanktogether with autologin/fingerprint to stop the prompts. Keep the backup —restoreputs the encrypted keyring back. - Per-user, no sudo. After
blankthe keyring is stored unencrypted — acceptable only because Margine encrypts the disk (LUKS + TPM2).
AI / local LLMs
ujust margine-ai
Installs the local-AI workflow: the Alpaca Flatpak (a chat GUI for local LLMs that bundles its own Ollama backend — no host install, no daemon). It detects your GPU and, on AMD, offers the in-sandbox ROCm plugin.
- Why: a one-command, fully offline/private ChatGPT-style chat. Models download on first launch from Alpaca's UI.
- Best: starter models —
llama3.1:8b(general),qwen2.5-coder:7b(code),phi3.5:3.8b(CPU-only/low-RAM). On an integrated AMD APU, if ROCm won't see the card, setHSA_OVERRIDE_GFX_VERSION=11.0.0in Alpaca → Preferences, or just skip ROCm and let Ollama's Vulkan backend run (usually works on APUs). ~8 GB VRAM is comfortable for ~7B models. - No sudo, no reboot (installs a system Flatpak; may show a polkit dialog). Undo with
margine-ai-remove.
ujust margine-ai-remove
Uninstalls Alpaca (and its AMD plugin). It deliberately keeps your downloaded models — delete ~/.var/app/com.jeffser.Alpaca/data/ by hand to reclaim that (multi-GB) space.
Testing ISOs in a VM
ujust margine-test-vm [iso] [name] [80]
Spins up a throwaway VM to test a Margine ISO on the real secure path: UEFI Secure Boot with Microsoft's keys pre-enrolled (so you exercise the MOK enrollment flow) + an emulated TPM 2.0 (so you can test LUKS auto-unlock). With an ISO it creates and boots a ready installer VM; with no ISO it defines a shut-off template to clone in virt-manager.
- Why: validate a freshly built ISO end-to-end on the exact firmware path real hardware uses — without touching your host, sudo, or copying multi-GB files.
- Best: pass the ISO as the first arg:
ujust margine-test-vm ~/Downloads/margine-<date>.iso. Then follow the printed walkthrough — enroll the MOK (passwordmargine-os, public by design), confirm withmokutil --sb-state, thenujust margine-tpm-unlock enableand reboot to test TPM2 unlock. The ISO can stay inserted (boot order ishd,cdrom, so after install the disk wins — no install loop). - Rootless on
qemu:///session(no sudo). Needs Bluefin DX's virt stack. Tear down withmargine-test-vm-remove.
ujust margine-test-vm-remove [margine-test-template]
Stops and fully deletes a test VM — domain, disk(s) and UEFI nvram. Defaults to the clone template; pass the exact name otherwise (virsh -c qemu:///session list --all to check). Rootless, no sudo, irreversible. Run it whenever margine-test-vm reports a name collision, then recreate.
Apps
ujust install-koofr [install|remove] (alias: ujust koofr)
Installs the Koofr Desktop cloud-sync client natively and rootless into ~/.koofr-dist (Koofr has no Flatpak/RPM — only a self-updating tarball, so it stays out of the read-only image and updates itself). It autostarts hidden to the system tray at login (the binary's -silent flag), while a manual launch from the menu opens the window normally.
- Best: re-run it to update (there's no separate updater). It persists the hidden-start preference into
~/.koofr/config.jsononly when Koofr isn't running, so quit Koofr before re-running.ujust install-koofr removeuninstalls the client and its launchers (it keeps your~/.koofrconfig and synced data). - No sudo, no reboot — fully per-user. Needs network +
jq(both present on Margine).