If you’ve ever done something like
ls -la ~, then you must have noticed that
your home directory is a mess of hidden files. This annoys the inner
perfectionist in me, as I never have more than a few files in any folder.
Everything is a nice tree structure.
To solve this problem, the XDG basedir specification exists. It is a collection guidelines that more or less specify where files should be. From a users perspective, files are one of the following:
- Configuration files, which go into
$HOME/.config. These files are essential to the user, but also possibly specific to the current system.
- Cache files, which go into
$HOME/.cache. These files are non-essential and should probably not be in back-ups.
- Data files, which go into
$HOME/.local/share. These files are just user data.
- Runtime files, which are sort of a personal tempdir. Their location is not specified, but your system should fill it in in the
XDG_RUNTIME_DIRenvironment variables. If it is not set, I default it to
All these locations can be overwritten (which has its uses) but I’m already content with this. I then set out to clean up my home dir to this spec. With a combination of the Arch wiki and a bit of Googling, I managed to clean up most of it. This includes some interesting hacks, so bare with me.
The easy ones
Most modern applications already support the XDG basedir specification, and you can just move the legacy configuration to the new location. In my case, this included:
- git (move
- transmission (move
- wireshark (move
- inkscape (move
- latexmk (move
The harder ones
After moving the files for the supported applications, we still have quite a few left. For these, I used a variety of environment variables and aliases to try to move the remaining files out of there.
tmux allows for specifying an alternate config file as a parameter with the
-f flag. The alias
tmux="tmux -f ~/.config/tmux/tmux.conf" allows to
make this a little nicer. It also takes an enviroment variable
which dictates where the session storage should be. It defaults to
/tmp, but I
have it set to
$XDG_RUNTIME_DIR/tmux. Note that it should exist as
won’t create it.
sqlite is similar, but not quite. In addition to a configuration file (the
.sqliterc) it also considers an init file which is run before executing
anything. We can use this init file as an alternative
sqliterc, but it is an
additional file and the original will still be sourced. My alias is
sqlite3='sqlite3 -init "~/.config/sqlite3/sqliterc"'.
composer is a nice example for how your application can support the XDG basedir specification without having it as default. Normally, it stores everything in
~/.composer, but you can override this using environment variables. I use
wine needs a place to store its emulated windows storage, which can be overwritten with the environment variable
WINEPREFIX. I have mine set to
weechat IRC client stores a lot into
~/.weechat, but has no separation between logs, config,
and other data. You can however specify an alternative directory in the
WEECHAT_HOME variable. I have mine set to
~/.config/weechat, but an argument
could be made for
~/.local/share/weechat as well. I use it for config mainly
so I prefer the former.
ipython and Jupyter notebooks store their history in
~/.ipython. You can
move this with the environment variables
I have mine set to
GIMP’s configuration is located in (in my case)
~/.gimp2.8, but you can
relocate it using the
GIMP2_DIRECTORY environment variable. Mine is set to
atom editor has no separation between data, config, or cache, but it does accept an
ATOM_HOME environment variable. I have mine in
I probably don’t use NodeJS the way it was intended to be used (don’t like
It uses an
.npmrc file for its configuration, but you can override that with
NPM_CONFIG_USERCONFIG variable. After doing that, we can use our new
config file to improve the storage of the location a little. My
~/.config/npm/npmrc is shown below. You probably need to update your path to
correct for the moved binary directory.
Vagrant stores the data for its virtual machines in
~/.vagrant but you can
change that using the
VAGRANT_HOME directive. I prefer
Rust’s package manager
~/.cargo for its data but it contains
mostly sources for the packages, so it is only cache. I override it with
OpenSSL maintains its random state on disk, to use up less randomness from the
system. It keeps it in
~/.rnd but you can move it with the
environment. I moved it to
$XDG_RUNTIME_DIR/rnd, since I don’t need/want to
persist this random state between reboots.
The impossible ones
Not everything can be done nicely. The specification itself acknowledges that
some legacy directories and files will always exist because too many programs
depend on them. These are most notably
programs have rejected the specification for one reason or another, and cannot
be easily moved.
vim has no (non-invasive) solution to move its dotdir, but you can move your
~/.vim/vimrc, which saves at least one directory entry.
zsh won’t have its files moved completely either, but you can specify the
ZDOTDIR variable which changes where the rest of the configuration is located. You can use your
zshenv to set it, which saves all but one entry in your home dir.
There are others, for which I have no reasonable solution at all, so if anyone has suggestions, I’m all ears. These are:
- Audacity (
- Ruby/Bundler/Gem (
- Any IDEA IDE
- LightDM (stores selected desktop file in
- Java (stores fonts in
- Maven (stores local repository in
- Firefox/Thunderbird (stores data in
- GNU parallels (mostly stores its temporaries in
- Nautilus (stores thumbnails in
I think I have spent a little too much time on this, but as it stands, I am happy with the results. Moving cache files to my actual cache directory has greatly reduced the size of my back-ups, and it is more neat in general.