Unclutter Your Home Directory

It's still a problem for many people: applications create directories and files directly under $HOME, not even using the freedesktop XDG standard for user directories.

(My filemanager is always set to show hidden files. If yours isn't, try Ctrl-H, you might be surprised what you find.)

Manual cleanup is often required after removing software, but how can we get directories out of the way even for software that's in use?

Before you start

None of the steps here will move existing files/directories, you will always need to do that manually. Whether you use environment variables or some other settings, often you will have to

  • stop all graphical programs
  • move existing directories to their new locations with terminal commands
  • immediately log out/in to activate the new settings
  • check if anything managed to write to the old location, if so, delete that
  • log out/in again => all should be clean now.
  • if it isn't, some apps/scripts are ignoring the new settings? Read on.

Environment variables

Many tips here involve environment variables. There's many different ways to set them for one or all users. This article explains it well.

Mostly we'll need per user settings.

Personally, I start a simple window manager session from ~/.bash_profile: XINITRC="$XDG_DATA_HOME/xorg/xinitrc" startx; therefore I don't know much about desktop environment or display manager specific things.

XDG User Directories

These should be set first of all. Check with

$> env | grep XDG

Not all of these are set manually, you'll likely want to set those that aren't present when your run that command, e.g.:

# also see system directories in /etc/profile
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_CACHE_HOME="$HOME/.cache"
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_STATE_HOME="$HOME/.local/state"

Move your diretories to their new destinations, then log out/in. This might already remove a lot of clutter.


These paths are the canonical defaults for XDG/freedesktop (but if you want to make sure software uses them you must still set them explicitely). If you want to change these paths, things get much trickier (for applications that use dbus). You will need to change them globally.

The fix is relatively simple but requires root privileges and a full reboot afterwards.

Add something like this to /etc/security/pam_env.conf:


This moves the usual ~/.config and ~/.cache folders out of sight, inside ~/.local.

@{HOME} refers to the home directory of a user as set in /etc/passwd.
Variables already set in /etc/security/pam_env.conf can be referenced again with e.g. ${XDG_CONFIG_HOME}.




Defaults to ~/.gnupg.

export GNUPGHOME='/some/other/dir'


By default, after each compilation, you get a ~/go folder.

# jetbrains.com/help/go/configuring-goroot-and-gopath.html
export GOPATH="/some/other/path/go"


By default, after each compilation, you get a ~/.cargo folder.

# doc.rust-lang.org/cargo/reference/environment-variables.html
export CARGO_HOME="/home/ssd256_data/user_homes/cargo"


export NPM_CONFIG_USERCONFIG='/some/other/dir/npm/rc'

This file (not a directory) should then also contain

cache = /some/other/dir/npm

which otherwise defaults to ~/.npm

Java applications

There's a very simple trick to get all Java stuff out of the way via the user.home option, which can be set permanently through the _JAVA_OPTIONS variable.

export _JAVA_OPTIONS='-Duser.home=/some/other/dir'

Further options can be added, space-separated. Example, including anti-aliasing for fonts and GTK look:

export _JAVA_OPTIONS='-Duser.home=/some/other/dir -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true  -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel swing.crossplatformlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel'



(Build system for the JVM) - defaults to ~/.gradle.

export GRADLE_USER_HOME="/some/other/dir"
# or
export GRADLE_OPTS="$GRADLE_OPTS -Dgradle.user.home=/som/other/dir"

Possibly the last option could also be added to _JAVA_OPTIONS.


Vim will detect the config file "$XDG_CONFIG_HOME/vim/vimrc" but it still tends to drop files right in your home folder.
There are ways to change it, but I'm relatively new to vim and not sure I got it working 100%.


By default, wine places itself in ~/.wine but one can change that with the WINEPREFIX environment variable. For example:



A very nice interactive commandline calculator. Unfortunately it keeps dropping .calc_history in my home folder. Fix:

export CALCHISTFILE="$XDG_DATA_HOME/calc_history"

The sad rest

Unfortunately there are still a lot of applications that cannot be configured in this way, or it's too much work to configure each and every one.

Most annoyingly Firefox (20 years!) and all its derivates. 😢

One can start an app with a different HOME directory, e.g.

$> HOME="$XDG_CONFIG_HOME/nameofgame" nameofgame

(this can have undesired side-effects)

Or write a wrapper script with specific command-line options as a drop-in replacement for the executable, e.g.:

~/.local/bin is in PATH. You can create an executable shell script therein named firefox:

/usr/bin/firefox --profile /path/to/profile "$@"

Since most .desktop files don't call executables with their full path, this would override starting firefox from a menu, too. Check for yourself with grep Exec= /usr/share/applications/*.desktop.


Many "classic" (old) games dump their configs and saves right in your home folder. Game managers can provide solutions. I chose to remove all "Games" categories from my graphical menu and use Lutris instead. It will find system-installed games.

It can be configured to override environment variables for all games. Overriding $HOME only seems to have the pleasant side-effect that it does not affect games that do respect the XDG spec. Screencast (GIF).


Still my favorite theme chooser (there are both gtk2 and gtk3 versions), but it insists on writing configuration to ~/.icons and ~/.gtkrc-2.0 instead of $XDG_DATA_HOME/icons and $GTK2_RC_FILES respectively. GTK3 is OK though.

A wrapperscript is required:


problem() {
    notify-send -a lxappearance -i dialog-warning "Something went wrong" "$*"


[ -r ~/.gtkrc-2.0 ] && {
    mv ~/.gtkrc-2.0 "$XDG_CONFIG_HOME/gtk-2.0/gtkrc" && \
    sed -i "s#\.gtkrc-2\.0\.mine#$XDG_CONFIG_HOME/gtk-2.0/gtkrc.mine#" "$XDG_CONFIG_HOME/gtk-2.0/gtkrc" \
    || problem 'moving ~/.gtkrc-2.0'
[ -d ~/.icons/default ] && {
    rm -rf "$XDG_DATA_HOME/icons/default" && \
    mv ~/.icons/default "$XDG_DATA_HOME/icons/" && rmdir ~/.icons \
    || problem 'removing ~/.icons'

exit $x


Fortunately the dillo browser does not object to changing the HOME environment variable; if this is the only FLTK application you use, you can also move ~/.fltk out of the way:

mkdir "$XDG_DATA_HOME/dillo"
mv ~/.{fltk,dillo} "$XDG_DATA_HOME/dillo/"

Now, in your personal bin directory (e.g. $HOME/.local/bin), create a dillo executable with the following content:

export HOME
exec /usr/bin/dillo "$@"

nss (~/.pki)

The ~/.pki directory belongs to nss. Long story short, it is possible to create the $XDG_DATA_HOME/pki folder and hope applications will use it, but not all of them do (notably chromium browsers).