In this article
- Two laptop generations, two profiles
- How does this become a complete desktop?
- What exactly does the X1 installer do?
- Install in steps you can follow
- The first few minutes on the desktop
- Understand the XMonad–Xmobar connection
- Check audio, Wi-Fi and battery deliberately
- Updates and returning to your own files
- Privacy and reviewed sources
Gruvnode is my personal laptop desktop: understandable, keyboard-driven and something I can provision again after reinstalling. The setup began on my former ThinkPad T480. Today, the active profile for my ThinkPad X1 Carbon lives in the same repository.
My “easy-going installer” handles repeated provisioning steps while keeping the configuration readable. This guide explains the current Arch profile, the installer workflow and the connection between XMonad and Xmobar. For Haskell basics, the XMonad introduction starts with a smaller file.
Two laptop generations, two profiles
| Profile | System | Role in the repository |
|---|---|---|
thinkpad-t480/ | Debian 13, X11 and XMonad | Historical setup for the previous laptop |
thinkpad-x1-carbon/ | Arch Linux, X11 and XMonad | Current profile for my X1 Carbon with 16 GB RAM |
The T480 remains as a readable record of the earlier setup. Its Intel Xorg and power settings are not automatically carried into the X1 profile. The newer profile uses the normal Xorg modesetting/libinput foundation and includes neither the old TLP configuration nor the T480 power tweaks.
Portable desktop decisions can move with the laptop. Hardware adjustments need evidence from the current machine. My museum workstation section gives more context about the daily laptop.
How does this become a complete desktop?
- XMonad arranges windows and manages keybindings.
- Xmobar displays the clock, battery and volume; the XMonad connection is prepared.
- Rofi and Kitty launch applications and provide a terminal.
- Picom and feh handle compositing and the wallpaper.
- PipeWire and WirePlumber supply audio and its management.
- NetworkManager with iwd handles networking and the Wi-Fi backend.
- BlueZ, Blueman, Thunar and Mousepad add Bluetooth and everyday file work.
Firmware packages, diagnostic utilities, OBS and other helpers complete the selection. Fastfetch is installed without being injected into shell startup. Gruvnode's desktop configuration therefore stays separate from your preferred shell presentation.
What exactly does the X1 installer do?
thinkpad-x1-carbon/install.sh first checks that it is running on Arch as a normal user. It uses sudo for specific system operations. The source separates the workflow into these steps:
- Fully update Arch and install the official package list.
- Build
yayfrom the AUR if needed, then install Google Chrome through yay. - Configure NetworkManager for iwd, enable networking/Bluetooth and start the audio user services.
- Deploy managed user files and helper scripts.
- Link the shared wallpaper and run
xmonad --recompile.
Gruvnode does not install Arch itself. It assumes an installed system with a normal user and sudo. Chrome currently belongs to the X1 profile. Official packages come through pacman; the AUR build is a separate step. Read the package list and AUR build files before adopting the setup.
The installer automatically confirms package operations and restarts NetworkManager. Run initial provisioning locally on the laptop and account for the network interruption. A small desktop does not mean the installer only changes one Haskell file.
Install in steps you can follow
Start with a working Arch installation. Before a full update, check Arch news for required manual intervention. If Git is missing, install it as part of a complete update:
sudo pacman -Syu --needed git
Clone the repository:
git clone https://github.com/dennishilk/gruvnode.git
Enter the current profile explicitly:
cd gruvnode/thinkpad-x1-carbon
Read its README and install.sh. The included validation checks files, shell syntax and expected configuration entries:
bash tests/validate.sh
Optional Shellcheck and Haskell checks run only when their tools are available. Passing validation is therefore not a hardware test. Make the installer executable:
chmod +x install.sh
Run it as your normal user without putting sudo in front:
./install.sh
Read the final output, including any backup path. After the first firmware/audio/Wi-Fi provisioning run, the profile recommends a reboot. Log in on a TTY afterwards and start the X11 session:
startx
~/.xinitrc sets the desktop environment and launches XMonad. The installer does not provision a complete graphical login manager.
The first few minutes on the desktop
| Keys | X1 profile action |
|---|---|
| Super + Enter | Kitty |
| Super + D | Rofi |
| Super + B / O / T | Chrome / OBS / Thunar |
| Super + J / K | Change window focus |
| Super + H / L | Shrink or expand the master area |
| Super + Space | Cycle Tall and Full |
| Super + Shift + R | Compile and restart XMonad |
Screenshot under ~/Pictures/Screenshots/ |
Mousepad opens through Rofi and deliberately has no dedicated binding. Normal windows tile; detected dialogs are centred and floated. Volume keys use PipeWire through wpctl; brightness keys call brightnessctl.
Understand the XMonad–Xmobar connection
In xmonad.hs, statusBarProp writes status information to the X11 property _XMONAD_LOG. withSB manages the associated bar within XMonad's lifecycle. Xmobar's Run XMonadLog plugin can read that information.
The current Xmobar template actually displays the clock, battery and volume:
, template = "}{ %date% %battery% %volume% "
Although the XMonadLog plugin is configured, its visible placeholder is absent. To display workspaces and the prepared window title as well, first back up the file:
cp -a --backup=numbered ~/.config/xmobar/xmobarrc ~/.config/xmobar/xmobarrc.before-tutorial
Replace only the existing template line with this example:
, template = "%XMonadLog% }{ %date% %battery% %volume% "
Restart XMonad so its managed bar starts again:
xmonad --restart
Check the left side while switching workspaces. Restore the original template line and restart to undo the exercise. The installed network helper is not automatically displayed in the current template either.
Check audio, Wi-Fi and battery deliberately
If the bar shows vol n/a, the helper could not query a usable default output. Start with:
wpctl status
To inspect network devices and their state, use:
nmcli device
NetworkManager manages Wi-Fi through its iwd backend. The profile does not call for separately enabling independent iwd management. The battery helper finds the first available BAT* device rather than assuming BAT0; a standalone AC can also mean it did not find a battery device.
Use xrandr to inspect external displays initially. The profile does not invent a dock's or monitor's identifiers in advance. Cameras and audio devices still need testing on the actual laptop.
Updates and returning to your own files
Existing managed user files are backed up before replacement under ${XDG_STATE_HOME:-~/.local/state}/gruvnode/backups/, in a dated run directory. The installer reports the precise path. This covers its selected files rather than providing a full system backup or automatic uninstaller.
If necessary, restore individual files from the reported backup. Compile a restored XMonad file and restart only after success. Package upgrades, AUR installations, services and NetworkManager system settings need their own return path; copying back a desktop file does not remove them.
To update the profile, return to its directory and fetch changes:
git pull --ff-only
Review the diff before running ./install.sh again. Save local customisations deliberately. The backup guide explains which extra paths and dependencies belong in your recovery plan.
Privacy and reviewed sources
Gruvnode requires no account of its own and does not automatically upload configuration backups. Software downloads contact GitHub, package repositories and the AUR. Chrome, OBS and other applications retain their own network and privacy behaviour. Bars and screenshots may display window titles or file paths.
The guide follows the current X1 profile and historical T480 installer, reviewed on 7 October 2026.