Use the XDG Base Directory specification


Alright, so as you guys know I have been very critical of Freedesktop in the past. Some of that I think is justified, some maybe less so. Today I'm going to talk about the complete opposite though. The XDG Base Directory specification, or what is in my opinion one of the best things Freedesktop have come up with.

What is XDG Base Directory?

XDG Base Directory is a specification by Freedesktop, but I would go as far as to call it a standard, because frankly if you're a developer who isn't following it, most end users hate you, myself included. I won't have you read the entire specification, so I will summarize the specification.

In the past, programs would just write configuration files, cache files, and other data wherever the hell the programmer decided that they should go. Perhaps this is practical to the programmer, but what ends up happening is users find that they have possibly hundreds of hidden files that they did not create.

The XDG Base Directory standard came around to solve this very real problem, by creating a few directories in the home directory, that programs can use for storing data, hence the name.

But what people tend to forget is that it doesn't necessarily have to be your home directory. You could put these directories anywhere your user has read and write permission, or hell, even /dev/null if you want to break stuff. This is why this specification rocks. But what are the directories and variables? There are many of them, but the most common are:

All of them are unset by default, but when developing a program you should still read and use them. $XDG_CONFIG_HOME is where user configuration files should be read from and written to. On most systems, it is set to ~/.config by default. Does that sound familiar?

$XDG_CACHE_HOME is where cache files should be stored. On most systems, it is set to ~/.cache by default. $XDG_DATA_HOME is for program data, and is set to ~/.local/share by default on most systems. All of these will probably sound familiar to you if you have been using GNU/Linux or even BSD operating systems for a decent amount of time.

A common misconception

No, by placing config files into ~/.config or cache files in ~/.cache, you are NOT supporting the XDG Base Directory specification. I see this very often in shell scripts especially, and I've been guilty of it as well but to properly support the specification, you need to check the variable. If the variable is unset, you should (but technically don't have to) use the default path.

In shell script for instance, you would do something along the lines of mkdir -p ${XDG_CONFIG_HOME:-$HOME/.config}/my-software. In C you would use getenv("XDG_CONFIG_HOME");. But in any case, it isn't hard.

Why follow the specification?

If you're an end user, this is most likely already obvious to you. If you were to run simply ls on your home directory, you probably wouldn't think it's that bad. But that's because the ls command doesn't show dotfiles. Run ls -a ~/ instead. Look at the absolutely insane amount of dotfiles. In fact, you likely have more configuration files than normal files you actually care about. Your home directory has turned into a dumpster for programs to throw their config files and cache into.

By following the specification, you're allowing your users a lot more choice over their home directory. At the end of the day, it's their home directory, not the program's home directory.

If you do not follow this specification, you are actively causing your users pain and suffering from having a cluttered home directory. You go out of your way to treat your user's home folder like a dumpster. I am a minimalist, and I don't use that many programs. I have 28 hidden files and directories in my $HOME folder. Now imagine how many dotfiles your average GNOME or KDE user would have on his or her computer.

Please, for the love of god, if you're a developer, follow the XDG Base Directory specification. It really should be the XDG Base Directory specification, and the only people who are preventing this from happening are stubborn developers like you.

Following the specification is easy

Following the specification is incredibly easy, and even if you're new to software development (like me), you can easily follow the specification. All you have to do to support the specification is the following:

  1. Check if the XDG variable is set. Depending on the type of file you're trying to store it will be different. For cache files, this is ${XDG_CACHE_HOME}, for config files this is ${XDG_CONFIG_HOME}, for general data this is ${XDG_DATA_HOME}.
  2. If it isn't set, use the default for that variable. For ${XDG_CACHE_HOME}, it would be ~/.cache, for ${XDG_CONFIG_HOME} it is ~/.config and for ${XDG_DATA_HOME} it is ~/.local/share.
  3. Create a directory inside whenever it makes sense to do so.

That's it. That's all you have to do. You're now one step closer to being a developer writing quality software, rather than a developer that makes your users consider throwing away their computers. It's not hard.

The only exception

The only exception where I think it is acceptable to not follow this standard, is when thousands of people heavily depend on a program, who require that the config file or cache path never change. There are a few such cases, Firefox being one notable example. I ultimately dislike having the .mozilla directory in my home directory, but the location changing could cause significant issues for a lot of people, who would have to adjust to it.

If your shiny new project doesn't support the XDG standard, especially if almost no people depend on it or its configuration file/cache file location, you have no excuse.


Some programs don't quite fully support the specification. The Arch wiki has an excellent article dedicated to software that can use the XDG standard, both programs that support it natively and programs that need a environment variable to be exported.

It's the XDG Base Directory standard. If you are a software developer, follow the standard. That's it for today, have a good day!


To post a comment, you must be logged in.