XDG compliance, or the overwhelming lack thereof
Quick; no time for questions! Open a terminal and run:
ls -A | wc -l
Thatâs the number of files, folders and other tidbits that have been placed in your $HOME (with
or without your blessing). Can you justify that number? Do you even know what is going on there?
Personally, I like to keep my home as clean as possible, so letâs take a look and try to do a little
spring-cleaning.
A brief background on XDG
XDG or âCross Desktop Groupâ (previously known as X Desktop Group) is an ongoing project with the goal of
improving UNIX-like operating systemsâ interoperability. They have a multitude of software projects and
specifications which you can find over at https://freedesktop.org. While their other projects are also interesting, the one weâre focused on during
this rant is the âXDG Desktop Base Directoriesâ specification - basedir for short.
At ~800 words, basedir is a short document which provides sensible defaults for the storage
location of user-specific files. It also defines some environment variables that can be set to override
the default locations. There are seven base directories for the following file types:
| File type | Default value | Environment Variable |
|---|---|---|
| data files | $HOME/.local/share |
XDG_DATA_HOME / XDG_DATA_DIRS |
| configuration files | $HOME/.config |
XDG_CONFIG_HOME / XDG_CONFIG_DIRS |
| state data | $HOME/.local/state |
XDG_STATE_HOME |
| non-essential (cached) data | $HOME/.cache |
XDG_CACHE_HOME |
| runtime files and other file objects | (no default value) | XDG_RUNTIME_DIR |
| executable files | $HOME/.local/bin |
(no environment variable) |
To put this information into context, letâs say we are writing an application called send-bees. It
sends bees over TCP/IP to a conveniently preexisting beehive, keeps a record of how many bees were
sent in a single bee-sending session, as well as the total number of bees sent. It also keeps a log of your
activity per session.
If send-bees respects the basedir, it will behave something like this:
- Look for the config file with the default amount of bees to send,
beehiveaddress, log policy, etc. under$XDG_CONFIG_HOME/send-bees/config(The file name itself is not specified, so anything goes here, e.g.send-bees.config). - Store the total quantity of bees sent in
$XDG_STATE_HOME/send-bees/current. - Open a socket under
$XDG_RUNTIME_DIR/send-bees/beehive-socket(once again, file names donât matter - folders do) - cache any bees sent during the current session in
$XDG_CACHE_HOME/send-bees/session, which later may get dumped to the total bees file
There are some benefits to this beyond than having things neatly structured. It also seems to be bothering me enough - to the point I feel it became rant-worthy. Letâs see what advantages we get from complying with the spec:
- config files are all in a single directory
$XDG_CONFIG_HOMEcontains only text files and can sensibly be version-controlled with git- configuring a new device to your liking is as simple as
cp -r /backup/.config ~(orgit clone git@host:user/config .configif you are cool) - data and state files are in an expected location, as opposed to ď˝ď˝ď˝ď˝ ď˝ď˝ď˝ ď˝ď˝ , depending on how the developer was feeling that day, and can easily be removed/analyzed/backed up
- your
$XDG_CACHE_HOMEcan be moved to atmpfs
What our application should most definitely not do, is to automatically create the
$HOME/.send-bees/ directory and dump everything in there, or perhaps even more perplexing, use
$XDG_CONFIG_HOME, implying it complies with basedir, but then dump everything,
including cache, state, runtime files, etc. into it and call it a day, effectively rendering any kind of
version controlling ineffective.
Unfortunately, most applications do not follow basedir, or require setting some environment
variables to look in the right places:
- Firefox, as well as any forks (e.g. LibreWolf) insist on creating
~/.mozilla/ - Thunderbird behaves similarly to Firefox
- Android Studio claims
~/.android, even though it allows you to configure what folders it should look in - Dart, Nim, Gradle, and other languages insist in creating their own
~/.{language}folders - Anything Chromium based (that includes every single Electron application) dumps all its files in
$XDG_CONFIG_HOME/app/
⌠and the list goes on.
Many of these have a workaround, but thatâs usually it - a hack. Meaning, every time I install a new piece of
software, I have to look up if it will fill my ~/.config with junk.
There are tools like xdg-ninja which can help
in cleaning up, but it would be great if more applications simply respected the spec.
*sigh*