XDG Base Directory

From ArchWiki
Revision as of 12:07, 4 January 2016 by Kynikos (talk | contribs) (this is very relevant: we are on the ArchWiki (i.e. wiki of Arch Linux), not on a freedesktop.org mirror)
Jump to navigation Jump to search

This article exists to catalog the growing set of software using the XDG Base Directory Specification introduced in 2003. This is here to demonstrate the viability of this specification by listing commonly found dotfiles and their support status. For those not currently supporting the Base Directory Specification, workarounds will be demonstrated to emulate it instead.

The workarounds will be limited to anything not involving patching the source, executing code stored in environment variables or compile-time options. The rationale for this is that configurations should be portable across systems and having compile-time options prevent that.

Hopefully this will provide a source of information about exactly what certain kinds of dotfiles are and where they come from.

The XDG Base Directory specification

Please read the full specification. This section will attempt to break down the essence of what it tries to achieve.

All paths defined must be absolute and valid.

Note: On Arch systems, only XDG_RUNTIME_DIR is set by default (see below): it is up to the user to define the other variables, see FS#31204 and [1].

User directories

    • Where user-specific configurations should be written (analogous to /etc).
    • Should default to HOME/.config.
    • Where user-specific non-essential (cached) data should be written (analogous to /var/cache).
    • Should default to HOME/.cache.
    • Where user-specific data files should be written (analogous to /usr/share).
    • Should default to HOME/.local/share.
    • Used for non-essential, user-specific data files such as sockets, named pipes, etc.
    • Not required to have a default value; warnings should be issued if not set or equivalents provided.
      Note: This variable is already set by pam_systemd (/run/user/$UID with systemd 228).
    • Must be owned by the user with an access mode of 0700.
    • Filesystem fully featured by standards of OS.
    • Must be on the local filesystem.
    • May be subject to periodic cleanup.
    • Modified every 6 hours or set sticky bit if persistence is desired.
    • Can only exist for the duration of the user's login.
    • Should not store large files as it may be mounted as a tmpfs.

System directories

    • List of directories seperated by : (analogous to PATH).
    • Should default to /usr/local/share:/usr/share.
    • List of directories seperated by : (analogous to PATH).
    • Should default to /etc/xdg.


These directories and files are unlikely to ever change, there is far too much historical baggage and most tools written expect these files and directories to exist in these locations.

While some of these tools are still in active development and maintainence, the developers are unwilling to accommodate for the necessary changes due to the aforementioned reasons.

Assumed to be present by many ssh daemons and clients such as DropBear and OpenSSH. OpenSSH Bug 2050
Part of Mozilla's NSS Project.
Like ~/.ssh, many programs expect this file to be here. These include projects like curl (CURLOPT_NETRC_FILE), ftp (NETRC), s-nail (NETRC), etc. While some of them offer alternative configurable locations, many do not such as w3m, wget and lftp.
Used by the various shells and display managers, this file is expected to be here much like ~/.netrc.


When contributing make sure to use the correct section.

Nothing should require code evaluation (such as vim and VIMINIT), patches or compile-time options to gain support and anything which does must be deemed hardcoded. Additionally if the process is too error prone or difficult, such as Haskell's cabal or eclipse, they should also be considered as hardcoded.

  • The first column should be the project name, ideally the command name if it is not ambigious, linked to their website or an appropriate internal wiki article.
  • The second column is for any legacy files and directories the project had, this is done so people can find them even if they are no longer read.
  • Try to find the commit or version a project switched to XDG Base Directory or any open discussions and include them in the next two columns.
  • Finally include any appropriate workarounds or solutions for unsupported projects. Be terse, this article assumes intelligence and good charity from the reader. If something is unclear then feel free to expend some explanation to clarify it.

Lastly, and this goes without saying, please verify that your solution is correct and functional.


Application Legacy Path Supported Since Discussion Notes
antimicro ~/.antimicro edba864 [2]
aria2 ~/.aria2 8bc1d37 [3]
blender ~/.blender 4293f473 [4]
burp f2388e9
chromium ~/.chromium 23057 [5] [6]
cower 8b70805
d-feet ~/.d-feet 7f6104b
dolphin-emu ~/.dolphin-emu a498c68 [7]
dunst 78b6e2b1 [8]
fontconfig ~/.fontconfig 8c255fb1
fontforge ~/.FontForge ~/.PfaEdit e4c2cc7432 [9] [10]
fontconfig ~/.fonts Use "$XDG_DATA_HOME"/fonts instead.
gconf ~/.gconf fc28caa7 [11]
git ~/.gitconfig 0d94427e
gstreamer-1.0 4e36f93924cf [12]
htop ~/.htoprc 93233a67
i3 ~/.i3 7c130fb54
i3status ~/.i3status.conf c3f7fc4994
inkscape ~/.inkscape 0.47 [13]
lgogdownloader ~/.gogdownloader d430af63d000 [14]
livestreamer ~/.livestreamerrc ea805917 [15]
llpp 3ab86f0cb Currently llpp places the configuration directly under XDG_CONFIG_HOME instead of creating a directory.
mc ~/.mc 1b9957058 0b7115647 ce401d797 [16]
mpd ~/.mpdconf 87b73284
mpv ~/.mpv cb250d490 [17]
mypaint ~/.mypaint cf723b74cd
newsbeuter ~/.newsbeuter 3c57824c5 [18] It is required to create both "$XDG_DATA_HOME"/newsbeuter and "$XDG_CONFIG_HOME"/newsbeuter [19]
OfflineIMAP ~/.offlineimaprc 5150de5 [20]
pcsx2 ~/.pcsx2 87f1e8f77 a9020c606 3b22f0fb0 0a012aec2 [21] [22]
ppsspp ~/.ppsspp 132fe47c7d [23]
pacman ~/.makepkg.conf 80eca94c8 [24]
PulseAudio ~/.pulse ~/.pulse-cookie 59a8618dcd9 87ae8307057 9ab510a6921 4c195bcc9d5 [25]
transmission ~/.transmission 5517 [26]
util-linux 570b32100
freerdp ~/.freerdp edf6e7258d
citra ~/.citra-emu f7c3193fec [27]
lftp ~/.lftp 21dc400 [28]
xsettingsd ~/.xsettingsd 4ecd7be
surfraw ~/.surfraw.conf ~/.surfraw.bookmarks 3e4591d8 bd8c427d f57fc718
milkytracker ~/.milkytracker_config eb487c55 [29]
sway ~/.sway/config 614393c09 [30]
opentyrian ~/.opentyrian 8d45ff2 [31]
neovim ~/.nvim ~/.nvimlog ~/.nviminfo 1ca5646bb [32] [33]
rr ~/.rr 02e7d41e [34]
wireshark ~/.wireshark b0b53fa5


Application Legacy Path Supported Since Discussion Notes
abook ~/.abook $ abook --config "$XDG_CONFIG_HOME"/abook/abookrc \

--datafile "$XDG_CACHE_HOME"/abook/addressbook

aspell ~/.aspell.conf
cargo ~/.cargo [35] [36] $ export CARGO_HOME="$XDG_DATA_HOME"/cargo
ccache ~/.ccache $ export CCACHE_DIR="$XDG_CACHE_HOME"/ccache
conky ~/.conkyrc 00481ee [37] $ conky --config="$XDG_CONFIG_HOME"/conky/conkyrc
crawl ~/.crawl $ export CRAWL_DIR="$XDG_DATA_HOME"/crawl/ # Trailing '/' is required.
coreutils ~/.dircolors $ source "$(dircolors "$XDG_CONFIG_HOME"/dircolors)"
ELinks ~/.elinks $ export ELINKS_CONFDIR="$XDG_CONFIG_HOME"/elinks
PulseAudio ~/.esd_auth Very likely generated by the module-esound-protocol-unix.so module. It can be configured to use a different location but it makes much more sense to just comment out this module in /etc/pulse/default.pa or "$XDG_CONFIG_HOME"/pulse/default.pa.
gdb ~/.gdbinit $ gdb -nh -x "$XDG_CONFIG_HOME"/gdb/init
gimp ~/.gimp-2.8 60e0cfe [38] [39] $ export GIMP2_DIRECTORY="$XDG_CONFIG_HOME"/gimp
gliv ~/.glivrc $ gliv --glivrc="$XDG_CONFIG_HOME"/gliv/glivrc
gpg ~/.gnupg $ export GNUPGHOME="$XDG_CONFIG_HOME"/gnupg

$ gpg2 --homedir "$XDG_CONFIG_HOME"/gnupg

gtk2 ~/.gtkrc-2.0 $ export GTK2_RC_FILES="$XDG_CONFIG_HOME"/gtk-2.0/gtkrc
gtk ~/.gtkrc $ export GTK_RC_FILES="$XDG_CONFIG_HOME"/gtk-1.0/gtkrc
httpie ~/.httpie [40] $ export HTTPIE_CONFIG_DIR="$XDG_CONFIG_HOME"/httpie
ipython/jupyter ~/.ipython $ export IPYTHONDIR="$XDG_CONFIG_HOME"/jupyter$ export JUPYTER_CONFIG_DIR="$XDG_CONFIG_HOME"/jupyter
isync ~/.mbsyncrc $ mbsync -c "$XDG_CONFIG_HOME"/isync/mbsyncrc
libice ~/.ICEauthority $ export ICEAUTHORITY="$XDG_RUNTIME_DIR"/X11/iceauthority
less ~/.lesshst $ export LESSHISTFILE="$XDG_CACHE_HOME"/less/history

$ export LESSHISTFILE=- can be used to disable this feature.

Mathematica ~/.Mathematica $ export MATHEMATICA_USERBASE="$XDG_CONFIG_HOME"/mathematica
mednafen ~/.mednafen $ export MEDNAFEN_HOME="$XDG_CONFIG_HOME"/mednafen
moc ~/.moc $ mocp -M "$XDG_CONFIG_HOME"/moc

$ mocp -O MOCDir="$XDG_CONFIG_HOME"/moc

MPlayer ~/.mplayer $ export MPLAYER_HOME="$XDG_CONFIG_HOME"/mplayer
mutt ~/.mutt [41] $ mutt -F "$XDG_CONFIG_HOME"/mutt/muttrc
set header_cache = $XDG_CACHE_HOME/mutt/headers
set message_cachedir = $XDG_DATA_HOME/mutt/messages
set mailcap_path = $XDG_CONFIG_HOME/mutt/mailcap
set record = $XDG_DATA_HOME/mutt/record/sent
ncmpcpp ~/.ncmpcpp $ ncmpcpp -c "$XDG_CONFIG_HOME"/ncmpcpp/config
notmuch ~/.notmuch-config [42] $ export NOTMUCH_CONFIG="$XDG_CONFIG_HOME"/notmuch/notmuchrc

$ export NMBGIT="$XDG_DATA_HOME"/notmuch/nmbug

ncurses ~/.terminfo $ export TERMINFO="$XDG_DATA_HOME"/terminfo # Precludes system path searching.

$ export TERMINFO_DIRS="$XDG_DATA_HOME"/terminfo:/usr/share/terminfo



python-setuptools ~/.python-eggs $ export PYTHON_EGG_CACHE="$XDG_CACHE_HOME"/python-eggs
readline ~/.inputrc $ export INPUTRC="$XDG_CONFIG_HOME"/readline/inputrc
screen ~/.screenrc $ export SCREENRC="$XDG_CONFIG_HOME"/screen/screenrc
tmux ~/.tmux.conf [43] [44] $ tmux -f "$XDG_CONFIG_HOME"/tmux/tmux.conf


urxvtd ~/.urxvt/urxvtd-hostname $ export RXVT_SOCKET="$XDG_RUNTIME_DIR"/urxvt/urxvt-"$(hostname)"
WeeChat ~/.weechat [45] $ export WEECHAT_HOME="$XDG_CONFIG_HOME"/weechat

$ weechat -d "$XDG_CONFIG_HOME"/weechat

wine ~/.wine [46] $ export WINEPREFIX="$XDG_DATA_HOME"/wine
xorg-xauth ~/.Xauthority $ export XAUTHORITY="$XDG_RUNTIME_DIR"/X11/xauthority
libx11 ~/.XCompose $ export XCOMPOSEFILE="$XDG_CONFIG_HOME"/X11/xcompose
xorg-xinit ~/.xinitrc $ export XINITRC="$XDG_CONFIG_HOME"/X11/xinitrc
xorg-xrdb ~/.Xresources ~/.Xdefaults Ultimately you should be using Xresources and since these resources are loaded via xrdb you can specify a path such as xrdb -load ~/.config/X11/xresources.
openscad ~/.OpenSCAD 7c3077b0f [47] Does not fully honour XDG Base Directory Specification, see [48]

Currently it hard-codes ~/.local/share.

libdvdcss ~/.dvdcss [49] $ export DVDCSS_CACHE="$XDG_DATA_HOME"/dvdcss
tig ~/.tigrc $ export TIGRC_USER="$XDG_CONFIG_HOME"/tig/tigrc
rlwrap ~/.*_history [50] $ export RLWRAP_HOME="$XDG_DATA_HOME"/rlwrap
uncrustify ~/.uncrustify.cfg $ export UNCRUSTIFY_CONFIG="$XDG_CONFIG_HOME"/uncrustify/uncrustify.cfg
xsel ~/.xsel.log [51] $ xsel --logfile "$XDG_CACHE_HOME"/xsel/xsel.log
emscripten ~/.emscripten ~/.emscripten_sanity ~/.emscripten_ports ~/.emscripten_cache__last_clear 3624 $ export EM_CONFIG="$XDG_CONFIG_HOME"/emscripten/config

$ export EM_CACHE="$XDG_CACHE_HOME"/emscripten/cache $ export EM_PORTS="$XDG_DATA_HOME"/emscripten/cache $ emcc --em-config "$XDG_CONFIG_HOME"/emscripten/config --em-cache "$XDG_CACHE_HOME"/emscripten/cache

stack ~/.stack [52] $ export STACK_ROOT="$XDG_DATA_HOME"/stack
subversion ~/.subversion [53][54] $ svn --config-dir "$XDG_CONFIG_HOME"/subversion
ltrace ~/.ltrace.conf $ ltrace -F "$XDG_CONFIG_HOME"/ltrace/ltrace.conf


Application Legacy Path Supported Since Discussion Notes
Apache Directory Studio ~/.ApacheDirectoryStudio
AMule ~/.aMule
cabal ~/.cabal [55] See discussion for potential workarounds. It is not very easy or straightforward but may be possible to emulate Base Directory compliance.
julia ~/.juliarc.jl ~/.julia_history [56] [57]
milkytracker ~/.milkytracker_config [58]
firefox ~/.mozilla [59]
gstreamer-0.10 ~/.gstreamer-0.10 Use gstreamer-1.0 instead.
python ~/.python_history All history from interactive sessions is saved to ~/.python_history by default since version 3.4, custom path can still be set the same way as in older versions (see this example).
procps-ng ~/.toprc [60]
vim ~/.vim ~/.vimrc ~/.viminfo Since 7.3.1178 vim will search for ~/.vim/vimrc if ~/.vimrc is not found.
set undodir=~/.cache/vim/undo " vim will not create this directory.
set directory=~/.cache/vim/swap " vim will not create this directory.
set backupdir=~/.cache/vim/backup " vim will not create this directory.
set viminfo+=n~/.cache/vim/viminfo
xdg-utils ~/.gnome For some reason the script xdg-desktop-menu hard-codes gnome_user_dir="$HOME/.gnome/apps". This is used by chromium amoung others.
SQLite ~/.sqlite_history
wpa_cli ~/.wpa_cli_history
xmonad ~/.xmonad [61]
eclipse ~/.eclipse [62] Option -Dosgi.configuration.area=@user.home/.config/.. overrides but must be added to "$ECLIPSE_HOME"/eclipse.ini" rather than command line which means you must have write access to $ECLIPSE_HOME. (Arch Linux hard-codes $ECLIPSE_HOME in /usr/bin/eclipse)
perf ~/.debug Hardcoded in tools/perf/util/config.c:18.
zsh ~/.zshrc ~/.zprofile ~/.zshenv ~/.zlogin ~/.zlogout ~/.zsh_history ~/.zhistory [63] Consider exporting ZDOTDIR=$HOME/.config/zsh in ~/.zshenv (this is hardcoded due to the bootstrap problem). You could also add this to /etc/zsh/zshenv and avoid the need for any dotfiles in your HOME. Doing this however requires root privilege which may not be viable and is system-wide.

export HISTFILE="$XDG_DATA_HOME"/zsh/history

bash ~/.bashrc ~/.bash_history ~/.bash_profile ~/.bash_login ~/.bash_logout [64] export HISTFILE="$XDG_DATA_HOME"/bash/history
lldb ~/.lldb ~/.lldbinit
emacs ~/.emacs ~/.emacs.d [65] It's possible to set HOME, but it has unexpected side effects. So far the most promising approach is modifying another Emacs environment variable to alter the load path and author your own site file which can manually load up your init file, but it changes the load process significantly.
mathomatic ~/.mathomaticrc ~/.matho_history History can be moved by using rlwrap mathomatic -r with the RLWRAP_HOME environment set appropriately.
mongodb ~/.mongorc.js ~/.dbshell [66] This Stack Overflow thread suggests a partial workaround using command-line switch --norc.
xombrero ~/.xombrero [67]
spectrwm ~/.spectrwm
ncmpc ~/.ncmpc
palemoon ~/.moonchild productions [68]
vimperator ~/.vimperatorrc [69] $ export VIMPERATOR_INIT=":source $XDG_CONFIG_HOME/vimperator/vimperatorrc"


CUPS ~/.cups [70]
dbus ~/.dbus [71] This should be avoidable with kdbus [citation needed].

Library and language support

C99: Cloudef's simple implementation.
Officially in directory since ab9d0810ce.
Builtin support via GLib.Environment.
See get_user_cache_dir, get_user_data_dir, get_user_config_dir, etc.

See also