Please, don't clutter my $HOME directory
April 1st 2024 | ~ 3 minute read
TL;DR
Would you just dump all your clothes and items all over the floor of your home? No, of course not, so why is my $HOME
directory different?
Does your application support Linux? Good. Use XDG Base Directory.
The problem
This has to be my biggest pet peeve of all. Developers who lack the basic understanding that configuration files for their applications have a well known place to be stored into. Different operating systems designate different directories for this purpose, but they all have some way to do it. For example, to store cache files, the three major operating systems use the following directories:
- Linux -
$HOME/.cache
- MacOS -
$HOME/Libraries/Caches
- Windows - go ask someone who uses Windows
But, for some cursed, unknowable reason, many application developers just choose to dump their cache and/or configuration files in the root of the $HOME
directory. Here's a random example of Joplin Notes doing this:
These developers should know better. It's a trivial thing to store these files where they belong, but, alas, they're either too lazy or too ignorant to do this.
The solution (for Linux at least)
I guess this is my excuse to talk about the XDG Base Directory specification. (Yes, I tricked you into reading an article about standards.) This document defines a way to determine which directories should be used for storing what kind of file. How is this done? By using one of the oldest yet simplest mechanisms there is, os environment variables.
A primer on environment variables for the uninitiated
Environment variables are nothing more than key, value pairs that store a small amount of textual data. The syntax is bone simple:
export FOO="bar"
Once set, any program with support for reading environment variables can access this information.
So, how does this work for XDG Base Directory?
Simple, the specification defines these user environment variables:
XDG_CONFIG_HOME
- Stores user-specific configuration
- Default:
$HOME/.config
XDG_CACHE_HOME
- Stores non-essential (cache), user-specific data
- Default:
$HOME/.cache
XDG_DATA_HOME
- Stores user-specific data that should be stored for future use
- Default:
$HOME/.local/share
XDG_STATE_HOME
- Stores user-specific state information
- Default:
$HOME/.local/state
XDG_RUNTIME_DIR
- Stores user-specific, non-essential data such as pipes and sockets
- Default (systemd):
/run/user/$UID
The specification also defines these environment variables for system-wide use:
XDG_DATA_DIRS
- List of
:
separated directories, analogous to$PATH
- Default:
/usr/local/share:/usr/share
XDG_CONFIG_DIRS
- List of
:
separated directories, analogous to$PATH
- Default:
/etc/xdg
With all of that being said, here's my configuration straight from my ~/.zshenv
file:
# XDG Base Directory
export XDG_CACHE_HOME="$HOME/.cache"
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_STATE_HOME="$HOME/.local/state"
Conclusion
Please, for the love of all things, don't just dump your configuration where it doesn't belong. I'm sure you can come up with an os-specific approach to properly store it. This specification should work just fine for most UNIX-like operating systems out there. And even if these variables aren't defined, it's still your job to program your application to store files properly. You can use these defaults as fallback, or try detecting the operating system your app is currently running on and implement their standard, but please, implement something. Don't clutter our $HOME
directories with stuff the user will, frankly, never need direct access to.
</rant>