# A pleasant Arch Linux setup Recently I distrohopped back to Arch Linux on my laptop and, given the opportunity for a fresh start, wanted to keep the setup tidy. In this post I note down a bunch of small changes I made that make my system more neat, lean and aesthetically pleasant by my judgement. I will (hopefully) periodically update this post as I find and implement new improvements. ## Environment variables First order of business is setting environment variables since so much else is configured through them. Traditionally one might put their variables into shell initialization files, such a `~/.profile` or `~/.bashrc`. I don't like this for a few reasons. First it pollutes my home directory with configuration files that don't belong there, and second it's not portable across shells. If you opt to use [fish shell](https://fishshell.com/) as I do then `.profile` will not be loaded by default, you'll have to [create a fishlogin file](https://superuser.com/a/1046884) that sources it manually. A better solution I found is to use [systemd's environment.d](https://www.freedesktop.org/software/systemd/man/latest/environment.d.html) to set variables set by the corresponding systemd user service (`user@.service`). I created the `~/.config/environment.d` directory and populated it with a few files for different types of assignments. For example here's the file I use to set my XDG base directories:

# ~/.config/environment.d/10-user-dirs.conf
XDG_CONFIG_HOME=$HOME/.config
XDG_CACHE_HOME=$HOME/.cache
XDG_DATA_HOME=$HOME/.local/share
XDG_STATE_HOME=$HOME/.local/state
This approach has a few benefits and a few downsides. It means my variables aren't dependent on my shell, that they're located in a common location, and have a dead-simple format that's not interspersed with other shell stuff. However it also means that `~/.config/` is necessarily my config home (after all you can't read `$XDG_CONFIG_HOME` before you've set it) and that reloading my environment requires reloading the user service and all services after it. So far the easiest way I've found to do this is to do a full `systemctl soft-reboot`. ## Keeping my `$HOME` clean In our blessed year of 2026 a nontrivial amount of programs still don't respect the [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir/latest/) by default. Thankfully a lot of them have environment-based configuration options I can use to fix that. To detect such cases I periodically run [xdg-ninja](https://github.com/b3nj5m1n/xdg-ninja) which helpfully lists out offending programs on my system as well as the fix, if any is available. Most fixes tend to be environment variables, and as such I have the following file in my `environment.d`

# ~/.config/environment.d/40-xdg-ninja.conf
CARGO_HOME=$XDG_DATA_HOME/cargo
RUSTUP_HOME=$XDG_DATA_HOME/rustup
# ...
## SSH agent Loading the SSH agent is yet another pain point when using a shell based approach. The Arch wiki even recommends using a [bash snippet](https://wiki.archlinux.org/title/SSH_keys#ssh-agent) in your `.bashrc` that uses `pgrep` to find the current running ssh agent instance and source its environment variable in the current shell as a method of dealing with it. Too janky for my tastes. Thankfully the very next section notes that a systemd user service for the agent is included with the `openssh` package that I can use it instead, so long as I set the `SSH_AUTH_SOCK` environment variable manually. Therefore an invocation of `systemctl --user enable ssh-agent.service` along with creating the following environment file solves my troubles.

# ~/.config/environment.d/30-ssh-agent.conf
SSH_AUTH_SOCK=$XDG_RUNTIME_DIR/ssh-agent.socket
## Xwayland By default the `xwayland-satellite` package does not start the satellite nor set up a service for it. It should be clear by now that I prefer using systemd services for this sort of thing rather than mechanisms like niri's `spawn-at-startup`. Therefore I dropped this [service file](https://github.com/Supreeeme/xwayland-satellite/blob/main/resources/xwayland-satellite.service) into my user services.

# ~/.config/systemd/user/xwayland-satellite.service
[Unit]
Description=Xwayland outside your Wayland
BindsTo=graphical-session.target
PartOf=graphical-session.target
After=graphical-session.target
Requisite=graphical-session.target

[Service]
Type=notify
NotifyAccess=all
ExecStart=/usr/local/bin/xwayland-satellite
# ^^ this needed adjustment ^^
StandardOutput=journal

[Install]
WantedBy=graphical-session.target
X based applications also expect the `DISPLAY` environment variable to be set so I created put that into my wayland workarounds environment file. That file also contains other environment-based hints to programs that they should really use wayland pretty-please.

# ~/.config/environment.d/20-wayland-hints.conf
DISPLAY=:1
ELECTRON_OZONE_PLATFORM_HINT=wayland
_JAVA_AWT_WM_NONREPARENTING=1
I'm not sure whether the exact number you choose for the display has any effect.