XDG Base Directory

From ArchWiki

This article summarizes the XDG Base Directory specification in #Specification and tracks software support in #Support.

Specification

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

Only XDG_RUNTIME_DIR is set by default through pam_systemd(8). It is up to the user to explicitly define the other variables according to the specification. Changing it might cause issues with pipewire and screen sharing on chromium.

See Environment variables#Globally for information on defining variables.

User directories

  • XDG_CONFIG_HOME
    • Where user-specific configurations should be written (analogous to /etc).
    • Should default to $HOME/.config.
  • XDG_CACHE_HOME
    • Where user-specific non-essential (cached) data should be written (analogous to /var/cache).
    • Should default to $HOME/.cache.
  • XDG_DATA_HOME
    • Where user-specific data files should be written (analogous to /usr/share).
    • Should default to $HOME/.local/share.
  • XDG_STATE_HOME
    • Where user-specific state files should be written (analogous to /var/lib).
    • Should default to $HOME/.local/state.
  • XDG_RUNTIME_DIR
    • 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.
    • 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.
    • pam_systemd sets this to /run/user/$UID.

System directories

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

Support

This article or section needs expansion.

Reason: The current supported/partial/hardcoded split is not detailed enough and can be misleading. The tables could be merged into one (with more fields added on how the programs work with the specification) or differently named categories could be used. (Discuss in Talk:XDG Base Directory#Add description of support categories)

This section 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.

Contributing

When contributing make sure to use the correct section.

Nothing should require code evaluation, patches or compile-time options to gain support and anything which does must be deemed hardcoded. Additionally, if the process is error prone or difficult, it should also be classified as hardcoded.

  • The first column should be either a link to an internal article, a Template:Pkg or a Template:AUR.
  • The second column is for any legacy files and directories the project had (one per line), this is done so people can find them even if they are no longer read.
  • In the third, 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 (two per line).
  • The last column should include any appropriate workarounds or solutions. Please verify that your solution is correct and functional.

Supported

Application Legacy Path Supported Since Discussion Notes
act ~/.actrc 1656

2195

[1] XDG_CONFIG_HOME/act/actrc

If present ~/.actrc will be merged with the XDG path config.

aerc fff1664 XDG_CONFIG_HOME/aerc/aerc.conf
ALSA ~/.asoundrc 577df36

1.2.3

[2] XDG_CONFIG_HOME/alsa/asoundrc
anacondaAUR ~/.conda/.condarc, ~/.conda/condarc, ~/.conda/condarc.d/, ~/.condarc 4.11.0 [3] [4]
Android Studio ~/.AndroidStudioX.X Android Studio 4.1
XDG_CONFIG_HOME/Google/AndroidStudioX.X
XDG_DATA_HOME/Google/AndroidStudioX.X
XDG_CACHE_HOME/Google/AndroidStudioX.X

Location overview by Google does not mention XDG - paths could be hardcoded instead of using the proper variable, though that is unlikely as Intellij IDEA, which Android Studio is based on, implements it properly as well

Anki ~/Anki, ~/Documents/Anki [5] [6] [7] Uses $XDG_DATA_HOME/Anki2 as default if no older location exists, can be changed by using anki -b <anki_dir>
antimicrox ~/.antimicro, ~/.antimicrox edba864 [8]
apvlvAUR ~/.apvlvrc [9] [10] Uses XDG_CONFIG_HOME/apvlv/apvlvrc now if it exist.
aria2 ~/.aria2 8bc1d37 [11]
XDG_CONFIG_HOME/aria2/
XDG_CACHE_HOME/aria2/
atuin ~/.config/atuin ~/.local/share/atuin 156893d
XDG_CONFIG_HOME/atuin/config.toml
XDG_DATA_HOME/atuin/history.db
asunder ~/.asunder ~/.asunder_album_artist ~/.asunder_album_genre ~/.asunder_album_title 2.9.0[dead link 2021-05-17 ⓘ] [12][dead link 2021-05-17 ⓘ] Uses XDG_CONFIG_HOME/asunder/asunder for ~/.asunder and XDG_CACHE_HOME/asunder/asunder_album_... for the other 3 files. Legacy paths are not removed after migration, they have to be deleted manually.
audacity ~/.audacity-data/ 3.2.0 [13] Uses new locations if legacy do not exist:
XDG_CONFIG_HOME/audacity
XDG_DATA_HOME/audacity
btop b5e709d XDG_CONFIG_HOME/btop
binwalk ~/.binwalk 2051757 [14] XDG_CONFIG_HOME/binwalk
bitwarden-cli ~/.config/Bitwarden CLI 1.7.1 [15]
XDG_CONFIG_HOME/Bitwarden CLI
XDG_DATA_HOME/audacity

The BITWARDENCLI_APPDATA_DIR environment variable takes precedence.

Currently contains a single data.json file with all the vault data, so it ought to belong in XDG_DATA_HOME

Blender ~/.blender 4293f47 [16]
byobu ~/.byobu 4.17 [17]

XDG_CONFIG_HOME/byobu

Legacy path takes precedence if present, or if XDG_CONFIG_HOME is not set.

cabal ~/.cabal/ 9f7dc55 v3.10.1.0 [18]
calcurse ~/.calcurse 04162d [19] [20]
XDG_CONFIG_HOME/calcurse
XDG_DATA_HOME/calcurse

If the legacy path ~/.calcurse is present, it will take precedence.

calibre
ccache ~/.ccache 4.0 [21]
XDG_CACHE_HOME/ccache
XDG_CONFIG_HOME/ccache/ccache.conf
catfish ~/.config/catfish af65ed25 [22]
clangd ~/.clangd fdf7dcc[dead link 2022-09-23 ⓘ] [23] XDG_CONFIG_HOME/clangd/config.yml

XDG_CACHE_HOME/clangd

Project specific configuration can be specified in proj/.clangd. Configuration is combined when this is sensible. In case of conflicts, user config has the highest precedence, then inner project, then outer project.

Composer ~/.composer 1.0.0-beta1 [24]
crossnote ~/.mume d714a82

0.8.13

[25] $XDG_CONFIG_HOME/mume

If the legacy path is present, it will take precedence.

ctags (universal-ctags) ~/.ctagsrc, .ctags.d 68da03a

8fb0b04

Issue 89

Pull request 2384

At start-up time, Universal-ctags loads files having file`.ctags` as a file extension under: $XDG_CONFIG_HOME/ctags

See Ctags Option files.

cURL ~/.curlrc 7.73.0 [26] XDG_CONFIG_HOME/.curlrc
CUPS ~/.cups/ 23b1be6 [27]

libcups added XDG support in v3 (still in beta). The version in the official repositories is still hardcoded to ~/.cups.

dconf
Dolphin emulator ~/.dolphin-emu a498c68 [28]
dr14_t.meter-gitAUR 7e777ca [29] XDG_CONFIG_HOME/dr14tmeter/
dunst 78b6e2b [30] XDG_CONFIG_HOME/dunst/
Emacs ~/.emacs ~/.emacs.d/init.el [31]

27.1

XDG_CONFIG_HOME/emacs/init.el

Legacy paths have precedence over XDG paths. Emacs will never create XDG_CONFIG_HOME/emacs/. Workaround for 26.3 or older: It's possible to set HOME, but it has unexpected side effects.

fish
fltk ~/.fltk/ 7308bcd [32] [33] Only supported in version 1.4.0, which has not been released yet (as of 9-July-2022)
fontconfig ~/.fontconfig ~/.fonts 8c255fb, [34] Config goes in XDG_CONFIG_HOME/fontconfig/fonts.conf or XDG_CONFIG_HOME/fontconfig/conf.d/, fonts are stored in XDG_DATA_HOME/fonts/
fontforge ~/.FontForge ~/.PfaEdit e4c2cc7

[35] [36]

freecad ~/.FreeCAD e7e2994ba

0.20.0

[37] Defaults to
XDG_CONFIG_HOME/FreeCAD
XDG_DATA_HOME/FreeCAD
XDG_CACHE_HOME/FreeCAD

legacy path can be used with FreeCAD --keep-deprecated-paths

freerdp ~/.freerdp edf6e72
Gajim ~/.gajim 3e777ea [38]
gconfAUR ~/.gconf fc28caa [39]
GDB ~/.gdbinit, ~/.gdb_history 11.1 XDG_CONFIG_HOME/gdb/gdbinit, export GDBHISTFILE="$XDG_DATA_HOME"/gdb/history
ghidra ~/.ghidra/ 3b0aac9 [40]
GIMP ~/.gimp-x.y ~/.thumbnails

60e0cfe 483505f

[41] [42]

Git ~/.gitconfig, ~/.gitignore, ~/.gitattributes, ~/.git-credentials, ~/.gitk 0d94427, dc79687, 684e40f Git Config, Git Attributes, Git Credentials, gitk XDG_CONFIG_HOME/git/config, XDG_CONFIG_HOME/git/ignore, XDG_CONFIG_HOME/git/attributes, XDG_CONFIG_HOME/git/credentials, XDG_CONFIG_HOME/git/gitk
gops 71c4255
gnuplot ~/.gnuplot_history a5562b1

[43]

goobookAUR ~/.goobookrc 3.5 [44] XDG_CONFIG_HOME/goobookrc
Godot Engine ~/.godot 73049d1

3.0-stable

[45]
GStreamer ~/.gstreamer-0.10 4e36f93 [46]
GTK 3
Haskell#Stack ~/.stack 2.9.3 [47] Defaults to legacy. Use export STACK_XDG=1 to make it compliant with the spec.

The old method of export STACK_ROOT="$XDG_DATA_HOME"/stack still works and takes priority [48][dead link 2024-07-30 ⓘ].

helm ~/.helm 3.0.0
htop ~/.htoprc 93233a6 XDG_CONFIG_HOME/htop/htoprc
httpie ~/.httpie 5af0874 [49]
hunspell ~/.hunspell_default. [50]
i3 ~/.i3 7c130fb
i3blocks, i3blocks-gitAUR [51]
i3status ~/.i3status.conf c3f7fc4
i3status-rust
IdeaVim ~/.ideavimrc 0.54.1-EAP [52] XDG_CONFIG_HOME/ideavim/ideavimrc
imagemagick
iotop-c ~/.config/iotop [53] [54]
Inkscape ~/.inkscape 0.47 [55]
ipython ~/.ipython 8.0.0 [56] Checks if $XDG_CONFIG_HOME/ipython (or ~/.config/ipython if XDG_CONFIG_HOME is unset) exists, otherwise it uses ~/.ipython.
iwd / iwctl ~/.iwctl_history d3e00d7f
intellij-idea-community-edition / intellij-idea-ultimate-editionAUR ~/.IntelliJIdeaXXXX.X 2020.1 [57]
XDG_CONFIG_HOME/JetBrains/IntelliJIdeaXXXX.X
XDG_DATA_HOME/JetBrains/IntelliJIdeaXXXX.X
XDG_CACHE_HOME/JetBrains/IntelliJIdeaXXXX.X
josm ~/.josm 11162 [58]
jupyter ~/.jupyter opt-in in 5.0, opt-out in 6.0, compulsory in 7.0 (changelog) XDG_CONFIG_HOME/jupyter
Kakoune
keynavAUR ~/.keynavrc XDG_CONFIG_HOME/keynav/keynavrc
less ~/.lesskey, ~/.lesshst 590

full support in 598

[59] The environment variables XDG_CONFIG_HOME and XDG_DATA_HOME must be set in version 590. In version 598 this is no longer necessary.

XDG_CONFIG_HOME/lesskey

XDG_STATE_HOME/lesshst or XDG_DATA_HOME/lesshst

latexmk (in texlive-binextra) ~/.latexmkrc

XDG_CONFIG_HOME/latexmk/latexmkrc

lftp ~/.lftp 21dc400 [60]
lgogdownloaderAUR ~/.gogdownloader d430af6 [61]
luarocks ~/.luarocks cd16cdd [62]
XDG_CONFIG_HOME/luarocks
XDG_CACHE_HOME/luarocks

If the legacy path ~/.luarocks is present, it will take precedence.

mangohud 65b90fc [63] XDG_CONFIG_HOME/MangoHud
mc ~/.mc

1b99570 0b71156 ce401d7

[64]
Mercurial ~/.hgrc

3540200 4.2

XDG_CONFIG_HOME/hg/hgrc.
mesa 87ab26b XDG_CACHE_HOME/mesa
milkytracker ~/.milkytracker_config eb487c5 [65]
mlterm ~/.mlterm/ 71df071 [66] XDG_CONFIG_HOME/mlterm/
mozc ~/.mozc 91cc1e1 [67]
mpd ~/.mpdconf 87b7328
mpv ~/.mpv cb250d4 [68]
msmtp ~/.msmtprc

af2f409 v1.6.7+

XDG_CONFIG_HOME/msmtp/config.
mutt ~/.mutt b17cd67 [69]
mypaint ~/.mypaint cf723b7
nano ~/.nano/ ~/.nanorc c16e79b [70]
ncmpcpp ~/.ncmpcpp

38d9f81 27cd86e

[71] [72]

ncmpcpp_directory should be set to avoid an error.log file in ~/.ncmpcpp.
Neovim ~/.nvim ~/.nvimlog ~/.nviminfo 1ca5646bb

[73] [74]

Nestopia UE ~/.nestopia/ 610c008 1.51.0 [75]
newsboat ~/.newsboat 3c57824 [76] It is required to create both directories [77]:

mkdir -p "$XDG_DATA_HOME"/newsboat "$XDG_CONFIG_HOME"/newsboat

node-gyp ~/.node-gyp 2b5ce52a [78]
np2kai-gitAUR ~/.config/np2kai ~/.config/xnp2kai 56a1cc2 [79]
notmuch ~/.notmuch-config [80] mkdir -p $XDG_CONFIG_HOME/notmuch/default; mv ~/.notmuch-config $XDG_CONFIG_HOME/notmuch/default/config
NSS ~/.pki 3.42 (da45424) [81] See Chromium for existing issue.
nteract-binAUR 4593e72 [82] [83] does not recognize workarounds for ipython/jupyter
ocaml-utopAUR ~/.utop-history

~/.utoprc

2.13.0

9729963

[84] XDG_STATE_HOME/utop/utop-history

XDG_CONFIG_HOME/utop/utoprc

OfflineIMAP ~/.offlineimaprc 5150de5 [85] XDG_CONFIG_HOME/offlineimap/config
openal ~/.alsoftrc 3c90ed9 XDG_CONFIG_HOME/alsoft.conf
opentyrianAUR ~/.opentyrian 39559c3 [86]
oscAUR ~/.oscrc ~/.osc_cookiejar 6bc2d3f

ebcf3de

github.com/openSUSE/osc/pull/940

github.com/osc/pull/940

XDG_CONFIG_HOME/osc/oscrc XDG_STATE_HOME/osc/cookiejar

Legacy path takes precedence if it exists

pam-u2f ~/.config/Yubico/u2f_keys ad52dd8 [87] XDG_CONFIG_HOME/Yubico/u2f_keys
pandoc-cli ~/.pandoc/ 0bed0ab [88]
PCManFM ~/.thumbnails 1.3.2
pcsx2AUR ~/.pcsx2

87f1e8f a9020c6 3b22f0f 0a012ae

[89] [90]
pdfsamAUR ~/.openjfx export _JAVA_OPTIONS=-Djavafx.cachedir="$XDG_CACHE_HOME"/openjfx
Pry ~/.pryrc ~/.pry_history

a0be0cc7 15e1fc92 e9d1be0e

[91]
python-autoimportAUR ~/.config/autoimport/config.toml 1.2.0 [92] XDG_CONFIG_HOME/autoimport/config.toml
python-black ~/.config/black 21.4b0 [93] XDG_CONFIG_HOME/black, XDG_CACHE_HOME/black/<version>/
python-pylint ~/.pylint.d 2.10 [94][dead link 2024-10-12 ⓘ] Formerly export PYLINTHOME="$XDG_CACHE_HOME"/pylint, global config still needs: export PYLINTRC="$XDG_CONFIG_HOME"/pylint/pylintrc
python-pip ~/.pip 6.0 [95]
python-pipx ~/.local/pipx c3d8de9 [96] For compatibility, pipx will revert to ~/.local/pipx if it exists. Implemented using python-platformdirs
python-poetry ~/.poetry [97] [98]
powershellAUR 6.0
ppsspp ~/.ppsspp 132fe47 [99]
procps-ng ~/.toprc af53e17

[100] [101]

pacman ~/.makepkg.conf 80eca94 [102]
panda3dAUR ~/.panda3d 2b537d2
pnpm ~/.pnpm-store [103] [104] [105]
poezioAUR
PulseAudio ~/.pulse ~/.pulse-cookie

59a8618 87ae830 9ab510a 4c195bc

[106] Steam might still create ~/.pulse-cookie. Add cookie-file = ~/.config/pulse/cookie to /etc/pulse/client.conf to get rid of it.
pyroomAUR
quodlibet ~/.quodlibet 3.10.0 [107]
qutebrowser
qtile

fd8686e 66d704b 51cff01

[108] Some optional bar widgets can create files and directories in non-compliant paths, but most often these are still configurable.
rclone ~/.rclone.conf 9d36258 [109]
retroarch
ripgrep-all ~/.cache/rga 963524b v0.10.3 [110] [111] [112]
rrAUR ~/.rr 02e7d41 [113]
RSpec ~/.rspec 5e395e2 [114]
rTorrent ~/.rtorrent.rc 6a8d332
RuboCop ~/.rubocop.yml 6fe5956 [115]
Ruby#RubyGems ~/.gem 3.0.0 (5c6269c) [116]
XDG_CONFIG_HOME/gem/gemrc
XDG_CONFIG_HOME/irb
XDG_DATA_HOME/gem
XDG_DATA_HOME/rdoc
sandboxd ~/.sandboxrc [117] [118] XDG_CONFIG_HOME/sandboxd/sandboxrc
scribus ~/.scribus 1.5.3
scummvm ~/.scummvmrc ~/.scummvm/ 7d014be [119] It is required to migrate data by hand.

mkdir "$XDG_CONFIG_HOME"/scummvm/ "$XDG_DATA_HOME"/scummvm mv ~/.scummvmrc "$XDG_CONFIG_HOME"/scummvm/scummvm.ini mv ~/.scummvm "$XDG_DATA_HOME"/scummvm/saves

sdcv ~/.stardict/ ~/.sdcv_history 958ec35 [120]
shellcheck ~/.shellcheckrc 581bcc3 XDG_CONFIG_HOME/shellcheckrc

See Shellcheck RC Files for more info.

snes9x ~/.snes9x 93b5f11 [121] By default, the configuration file is left blank with intention that the user will fill it at their will (through the gui or manually).
spectrwm ~/.spectrwm a30bbb [122]
Streamlink ~/.livestreamerrc ea80591 [123]
sublime-text-devAUR build 4105 Prior to build 4105, the cache was placed in XDG_CONFIG_HOME/sublime-text-3/Cache.
surfraw ~/.surfraw.conf ~/.surfraw.bookmarks

3e4591d bd8c427 f57fc71

sway ~/.sway/config 614393c [124] XDG_CONFIG_HOME/sway/config
sxhkd
systemd
teeworlds ~/.teeworlds [125]
termite
tig ~/.tigrc, ~/.tig_history 2.2 [126] ~/.local/share/tig directory must exist, writes to ~/.tig_history otherwise.
TigerVNC ~/.vnc 1.14.0 [127]
Theming (desktop) ~/.icons/, ~/.themes/ [128] XDG_DATA_HOME/icons

XDG_DATA_HOME/themes

For Qt programs, GTK or Qt programs on Wayland to use cursors in XDG_DATA_HOME/icons, the XCURSOR_PATH environment variable needs to be configured.

tmux ~/.tmux.conf 3.1 [129] 3.1 introduced ~/.config/tmux/tmux.conf and in 3.2 XDG_CONFIG_HOME/tmux/tmux.conf was added
tmuxp ~/.tmuxp 1.5.0 [130] Fixed in 1.5.2
tmuxinatorAUR ~/.tmuxinator 2636923 [131]
Transmission ~/.transmission b71a298
util-linux 570b321
yapf a0b51d2 [132] $XDG_CONFIG_HOME/yapf/style
Uzbl c6fd63a [133]
vale ~/.vale.ini 3.0.0
vim ~/.vim, ~/.vimrc, ~/.viminfo c9df1fb [134] XDG_CONFIG_HOME/vim/vimrc

See :h xdg-base-dir for more details.

The viminfo file can be set with :set viminfofile=

vimb
VirtualBox ~/.VirtualBox 4.3 [135]
vis ~/.vis

68a25c7 d138908

[136]
VLC ~/.vlcrc 16f32e1 [137]
warsow ~/.warsow-2.x 98ece3f [138]
WeeChat ~/.weechat [139]

3.2

[140] [141][dead link 2023-05-06 ⓘ]
XDG_CONFIG_HOME/weechat
XDG_CACHE_HOME/weechat
XDG_DATA_HOME/weechat
Wireshark ~/.wireshark b0b53fa[dead link 2022-09-23 ⓘ]
wxWidgets [142]
XKB ~/.xkb
Xsettingsd ~/.xsettingsd b4999f5
xmobar ~/.xmobarrc 7b0d6bf[dead link 2024-07-30 ⓘ]

9fc6b37[dead link 2024-07-30 ⓘ] eaccf70[dead link 2024-07-30 ⓘ]

[143][dead link 2024-07-30 ⓘ]

[144][dead link 2024-07-30 ⓘ]

XDG_CONFIG_HOME/xmobar/xmobarrc
xmonad ~/.xmonad/ 40fc10b

[145] [146]

All of these must exist, otherwise it gives up and falls back to ~/.xmonad/ for each:
XDG_CACHE_HOME/xmonad
XDG_CONFIG_HOME/xmonad
XDG_DATA_HOME/xmonad

Alternatively, it always respects XMONAD_CACHE_DIR, XMONAD_CONFIG_DIR, and XMONAD_DATA_DIR.

xonsh ~/.xonshrc [147] $XDG_CONFIG_HOME/xonsh/rc.xsh
xournalpp ~/.xournalpp 20db937f

1.1.0

[148]

[149]

xsel ~/.xsel.log ee7b481 [150]
Zim e42b8b0
 $XDG_CONFIG_HOME/zim/preferences.conf
 $XDG_CONFIG_HOME/zim/notebooks.list
zoxide ~/.zo 0.3.0 [151]
zutils ~/.zutilsrc 1.12
$XDG_CONFIG_HOME/zutils.conf

Partial

Application Legacy Path Supported Since Discussion Notes
abookAUR ~/.abook abook --config "$XDG_CONFIG_HOME"/abook/abookrc --datafile "$XDG_DATA_HOME"/abook/addressbook
ack ~/.ackrc [152] export ACKRC="$XDG_CONFIG_HOME/ack/ackrc"
Ansible ~/.ansible 2.14 [153] [154] [155]
export ANSIBLE_HOME="${XDG_CONFIG_HOME}/ansible"
export ANSIBLE_CONFIG="${XDG_CONFIG_HOME}/ansible.cfg"
export ANSIBLE_GALAXY_CACHE_DIR="${XDG_CACHE_HOME}/ansible/galaxy_cache"
[156]

The remote's ~/.ansible/tmp can be moved by setting remote_tmp = ${XDG_CONFIG_HOME}/ansible/tmp in an appropriate ansible.cfg. [157] [158]

asdf-vmAUR ~/.asdfrc, ~/.asdf/ [159] export ASDF_CONFIG_FILE="${XDG_CONFIG_HOME}/asdf/asdfrc", export ASDF_DATA_DIR="${XDG_DATA_HOME}/asdf"
aspell ~/.aspell.conf [160] Very incomplete. The following re-locates the en dictionaries, but additional possible dictionaries are not specificed here for brevity. export ASPELL_CONF="per-conf $XDG_CONFIG_HOME/aspell/aspell.conf; personal $XDG_DATA_HOME/aspell/en.pws; repl $XDG_DATA_HOME/aspell/en.prepl"
aws-cli ~/.aws 1.7.45 [161] export AWS_SHARED_CREDENTIALS_FILE="$XDG_CONFIG_HOME"/aws/credentials, export AWS_CONFIG_FILE="$XDG_CONFIG_HOME"/aws/config
bash-completion ~/.bash_completion export BASH_COMPLETION_USER_FILE="$XDG_CONFIG_HOME"/bash-completion/bash_completion
bashdbAUR ~/.bashdbinit, ~/.bashdb_hist Like documented at [162], you can specify a file to run commands from. Thus, move the init file to XDG_CONFIG_HOME/bashdb/bashdbinit and create an alias alias bashdb='bashdb -x ${XDG_CONFIG_HOME:-$HOME/.config}/bashdb/bashdbinit'. Unfortunately the history file is hardcoded [163].
bazaar ~/.bazaar, ~/.bzr.log 2.3.0 [164] Discussion in upstream bug states that bazaar will use ~/.config/bazaar if it exists. The logfile ~/.bzr.log might still be written.
bogofilter ~/.bogofilter 0.7.5 [165] export BOGOFILTER_DIR="$XDG_DATA_HOME"/bogofilter
btpd-gitAUR ~/.btpd/ [166] btpd -d "$XDG_DATA_HOME"/.btpd

HOME="$XDG_DATA_HOME" btcli

bunAUR ~/.bun/ [167] Bun will prioritize using $XDG_CONFIG_HOME, $XDG_CACHE_HOME, and/or $XDG_DATA_HOME when these have explicitly been set. As an alternative, export BUN_INSTALL="$XDG_DATA_HOME"/bun can be used to set bun's main location for its directories.
calc ~/.calc_history
export CALCHISTFILE="$XDG_CACHE_HOME"/calc_history
Rust#Cargo ~/.cargo [168] [169] [170] [171] export CARGO_HOME="$XDG_DATA_HOME"/cargo
cataclysm-dda ~/.cataclysm-dda 0.D-1 [172] partial support due to required compile time option
cd-bookmark ~/.cdbookmark [173] export CD_BOOKMARK_FILE=$XDG_CONFIG_HOME/cd-bookmark/bookmarks

or use the fork that has native XDG support: [174]

cgdb ~/.cgdb [On master branch, but no release yet] [175] [176] Set export CGDB_DIR=$XDG_CONFIG_HOME/cgdb and move the config file to XDG_CONFIG_HOME/cgdb/cgdbrc
chez-schemeAUR ~/.chezscheme_history petite --eehistory "$XDG_DATA_HOME"/chezscheme/history
chktex in texlive-binextra ~/.chktexrc Move the config file to $XDG_CONFIG_HOME/chktex/.chktexrc (mind the leading dot) and export CHKTEXRC=$XDG_CONFIG_HOME/chktex
Chromium ~/.chromium, ~/.pki 23057 [177] [178] [179] Deliberately (according to these sources) clobbers ~/.config by writing hundreds of megabytes of cache data into it. Quite unsupported.
Chromium creates .pki due to not setting up NSS properly even though NSS itself allows using XDG spec now. This results in downstream from it not working as well (Qt WebEngine especially affecting many cases like KMail and etc.)
cinelerra ~/.bcast5 [180] export CIN_CONFIG="$XDG_CONFIG_HOME"/bcast5
conky ~/.conkyrc 00481ee [181] conky --config="$XDG_CONFIG_HOME"/conky/conkyrc
claws-mail ~/.claws-mail [182] claws-mail --alternate-config-dir "$XDG_DATA_HOME"/claws-mail
coreutils ~/.dircolors eval $(dircolors "$XDG_CONFIG_HOME"/dircolors)
crawl ~/.crawl The trailing slash is required:

export CRAWL_DIR="$XDG_DATA_HOME"/crawl/

clusterssh ~/.clusterssh/ alias cssh="cssh --config-file '$XDG_CONFIG_HOME/clusterssh/config'"
$XDG_CONFIG_HOME/clusterssh/config
extra_cluster_file=$HOME/.config/clusterssh/clusters
extra_tag_file=$HOME/.config/clusterssh/tags

Despite this, clusterssh will still create ~/.clusterssh/.

CUDA ~/.nv export CUDA_CACHE_PATH="$XDG_CACHE_HOME"/nv
dict ~/.dictrc dict -c "$XDG_CONFIG_HOME"/dict/dictrc
discord ${XDG_CONFIG_HOME}/discord As of version 0.0.27:

Undocumented, though actively used: export DISCORD_USER_DATA_DIR="${XDG_DATA_HOME}"

Source: <discord_system_package_root>/resources/app.asar.

Docker ~/.docker export DOCKER_CONFIG="$XDG_CONFIG_HOME"/docker
docker-machine ~/.docker/machine export MACHINE_STORAGE_PATH="$XDG_DATA_HOME"/docker-machine
DOSBox ~/.dosbox/dosbox-0.74-2.conf [183] dosbox -conf "$XDG_CONFIG_HOME"/dosbox/dosbox.conf
dub ~/.dub v1.30.0-beta.1 Dub uses the ~/.dub directory for both user settings and caching downloaded packages. The directory can only be moved as a whole, using export DUB_HOME="path/to/new/dub".
Electrum Bitcoin Wallet ~/.electrum c121230 export ELECTRUMDIR="$XDG_DATA_HOME/electrum"
ELinks ~/.elinks export ELINKS_CONFDIR="$XDG_CONFIG_HOME"/elinks
elixir ~/.mix, ~/.hex afaf889 [184] [185] Elixir does not fully conform to XDG specs, it will use XDG only if the MIX_XDG variable is set to a special value, otherwise it will by default use legacy path.

export MIX_XDG="true"

Elm ~/.elm export ELM_HOME="$XDG_CONFIG_HOME"/elm
factorioAUR ~/.factorio/ [186] [187] Factorio supports manually specifying data paths with a config file: [188]
__Game_Install_directory/config-path.cfg
use-system-read-write-data-directories=true
__Game_Install_directory/config/config.ini
[path]
read-data=__PATH__executable__/../../data
write-data=.local/share/factorio
fceux ~/.fceux/ [189] export FCEUX_HOME="$XDG_CONFIG_HOME"/fceux. Fceux will create .fceux directory inside $FCEUX_HOME.
FFmpeg ~/.ffmpeg export FFMPEG_DATADIR="$XDG_CONFIG_HOME"/ffmpeg
flutterAUR ~/.flutter, ~/.flutter_settings, ~/.flutter_tool_state, ~/.pub-cache [190]
fzf-gitAUR ~/.fzf.bash, ~/.fzf.zsh [191] The shell init files will be installed to XDG_CONFIG_HOME/fzf if the installation script is called with --xdg for example /usr/local/opt/fzf/install --xdg.
emscripten ~/.emscripten, ~/.emscripten_sanity, ~/.emscripten_ports, ~/.emscripten_cache__last_clear [192] 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
get_iplayerAUR ~/.get_iplayer export GETIPLAYERUSERPREFS="$XDG_DATA_HOME"/get_iplayer
getmail ~/.getmail/getmailrc getmail --rcfile="$XDG_CONFIG_HOME/getmail/getmailrc" --getmaildir="$XDG_DATA_HOME/getmail"
ghc ~/.ghci [193] [194] Supported upstream from 9.4.1 [195], but as of 2022-09-24 Arch package is 9.0.2 and not yet up-to-date.
ghcup-hs-binAUR ~/.ghcup [196] [197] export GHCUP_USE_XDG_DIRS=true

The environment variable GHCUP_USE_XDG_DIRS can be set to any non-empty value. See [198].

glivAUR ~/.glivrc gliv --glivrc="$XDG_CONFIG_HOME"/gliv/glivrc
gnuradio ~/.gnuradio [199] GNU Radio:

export GR_PREFS_PATH="$XDG_CONFIG_HOME"/gnuradio

GNU Radio Companion: export GRC_PREFS_PATH="$XDG_CONFIG_HOME"/gnuradio/grc.conf

GnuPG ~/.gnupg [200] [201] export GNUPGHOME="$XDG_DATA_HOME"/gnupg, gpg2 --homedir "$XDG_DATA_HOME"/gnupg

Note that this currently does not work out-of-the-box using systemd user units and socket-based activation, since the socket directory changes based on the hash of $GNUPGHOME. You can get the new socket directory using gpgconf --list-dirs socketdir and have to modify the systemd user units to listen on the correct sockets accordingly. You also have to use the following gpg-agent.service drop-in file (or otherwise pass the GNUPGHOME env var to the agent running in systemd), or you might experience issues with "missing" private keys:

[Service]
Environment="GNUPGHOME=%h/.local/share/gnupg"

If you use GPG as your SSH agent, set SSH_AUTH_SOCK to the output of gpgconf --list-dirs agent-ssh-socket instead of some hardcoded value.

Go ~/go [202] export GOPATH="$XDG_DATA_HOME"/go, export GOMODCACHE="$XDG_CACHE_HOME"/go/mod

If GOMODCACHE is not set, it defaults to $GOPATH/pkg/mod (see [203]). GOCACHE is supported and defaults to $XDG_CACHE_HOME/go-build (see [204]).

Google Earth ~/.googleearth Some paths can be changed with the KMLPath and CachePath options in ~/.config/Google/GoogleEarthPlus.conf
gopass ~/.password-store Override settings in ~/.config/gopass/config.yml:
~/.config/gopass/config.yml
root:
path: gpgcli-gitcli-fs+file:///home/<userid>/.config/password-store
gpodder ~/gPodder GPODDER_DOWNLOAD_DIR sets the download folder. GPODDER_HOME - where config and database files are stored, downloads also if GPODDER_DOWNLOAD_DIR is not set.
GQ LDAP client ~/.gq, ~/.gq-state 1.51 export GQRC="$XDG_CONFIG_HOME"/gqrc, export GQSTATE="$XDG_DATA_HOME"/gq/gq-state, mkdir -p "$(dirname "$GQSTATE")"
Gradle ~/.gradle [205]

[206]

export GRADLE_USER_HOME="$XDG_DATA_HOME"/gradle
GTK 1 ~/.gtkrc export GTK_RC_FILES="$XDG_CONFIG_HOME"/gtk-1.0/gtkrc
GTK 2 ~/.gtkrc-2.0 export GTK2_RC_FILES="$XDG_CONFIG_HOME/gtk-2.0/gtkrc":"$XDG_CONFIG_HOME/gtk-2.0/gtkrc.mine"

If Lxappearance is used, ~/.gtkrc-2.0 may keep being created because it is where clicking "Apply" customizations writes to. The path is hardcoded in Lxappearance, but simply being an output file, the settings can be repeatedly moved to the location.

hledger ~/.hledger.journal [207] export LEDGER_FILE="$XDG_DATA_HOME"/hledger.journal
Houdini ~/houdiniMAJOR.MINOR) [208]

[209]

export HOUDINI_USER_PREF_DIR="$XDG_CACHE_HOME"/houdini__HVER__

The value of this variable must include the substring __HVER__, which will be replaced at run time with the current MAJOR.MINOR version string.

imapfilterAUR ~/.imapfilter export IMAPFILTER_HOME="$XDG_CONFIG_HOME/imapfilter"
IPFS ~/.ipfs export IPFS_PATH="$XDG_DATA_HOME"/ipfs
irb ~/.irbrc
~/.profile
$ export IRBRC="$XDG_CONFIG_HOME"/irb/irbrc
"$XDG_CONFIG_HOME"/irb/irbrc
IRB.conf[:SAVE_HISTORY] ||= 1000
IRB.conf[:HISTORY_FILE] ||= File.join(ENV["XDG_DATA_HOME"], "irb", "history")
irssi ~/.irssi [210] irssi --config="$XDG_CONFIG_HOME"/irssi/config --home="$XDG_DATA_HOME"/irssi
isync ~/.mbsyncrc [211] mbsync -c "$XDG_CONFIG_HOME"/isync/mbsyncrc
Java#OpenJDK ~/.java/.userPrefs [212] export _JAVA_OPTIONS=-Djava.util.prefs.userRoot="$XDG_CONFIG_HOME"/java
jupyter ~/.jupyter 5.0.0rc0 [213] [214] python-jupyter-core < v5.0.0:

export JUPYTER_CONFIG_DIR="$XDG_CONFIG_HOME"/jupyter

v5.0.0 <= python-jupyter-core < v6.0.0:

export JUPYTER_PLATFORM_DIRS="1" (see [215])

python-jupyter-core >= v6.0.0: full support (via python-platformdirs) enabled by default

k9s ~/.k9s 0.20.4 [216] export K9SCONFIG="$XDG_CONFIG_HOME"/k9s
KDE ~/.kde, ~/.kde4 [217] export KDEHOME="$XDG_CONFIG_HOME"/kde
keychain ~/.keychain [218] [219] keychain --absolute --dir "$XDG_RUNTIME_DIR"/keychain
kodi ~/.kodi [220] [221] KODI_DATA=$XDG_DATA_HOME/kodi
kscriptAUR ~/.kscript [222] export KSCRIPT_CACHE_DIR="$XDG_CACHE_HOME"/kscript
ledger ~/.ledgerrc, ~/.pricedb [223] ledger --init-file "$XDG_CONFIG_HOME"/ledgerrc
Leiningen ~/.lein, ~/.m2 export LEIN_HOME="$XDG_DATA_HOME"/lein

to change the m2 repo location used by leiningen look here: Leiningen#m2_repo_location

libdvdcss ~/.dvdcss [224] export DVDCSS_CACHE="$XDG_DATA_HOME"/dvdcss
libice ~/.ICEauthority [225] export ICEAUTHORITY="$XDG_CACHE_HOME"/ICEauthority

Make sure XDG_CACHE_HOME is set beforehand to directory user running Xorg has write access to.

Do not use XDG_RUNTIME_DIR as it is available after login. Display managers that launch Xorg (like GDM) will repeatedly fail otherwise.

LibreOffice [226] Libreoffice stores everything in $XDG_CONFIG_HOME/libreoffice/4/user/, including runtime files, user data, cache and extensions. Some of these can be changed unter Tools > Options > LibreOffice > Paths
libx11 ~/.XCompose, ~/.compose-cache export XCOMPOSEFILE="$XDG_CONFIG_HOME"/X11/xcompose, export XCOMPOSECACHE="$XDG_CACHE_HOME"/X11/xcompose
ltrace ~/.ltrace.conf ltrace -F "$XDG_CONFIG_HOME"/ltrace/ltrace.conf
lynx /etc/lynx.cfg export LYNX_CFG="$XDG_CONFIG_HOME"/lynx.cfg
m17n-db ~/.m17n.d [227]
maptool-binAUR ~/.maptool-rptools [228]
/opt/maptool/lib/app/MapTool.cfg
[JavaOptions]
-DMAPTOOL_DATADIR=.local/share/maptool-rptools

However, no way to change the location of this configuration file.

maven ~/.m2 [229] export MAVEN_OPTS=-Dmaven.repo.local="$XDG_DATA_HOME"/maven/repository

, mvn -gs "$XDG_CONFIG_HOME"/maven/settings.xml and set <localRepository> as appropriate in settings.xml

Mathematica ~/.Mathematica export MATHEMATICA_USERBASE="$XDG_CONFIG_HOME"/mathematica
maxima ~/.maxima export MAXIMA_USERDIR="$XDG_CONFIG_HOME"/maxima
mednafen ~/.mednafen export MEDNAFEN_HOME="$XDG_CONFIG_HOME"/mednafen
minikube ~/.minikube [230] export MINIKUBE_HOME="$XDG_DATA_HOME"/minikube

Creates a further .minikube directory in MINIKUBE_HOME for whatever reason.

mitmproxy ~/.mitmproxy alias mitmproxy="mitmproxy --set confdir=$XDG_CONFIG_HOME/mitmproxy", alias mitmweb="mitmweb --set confdir=$XDG_CONFIG_HOME/mitmproxy"
MOC ~/.moc mocp -M "$XDG_CONFIG_HOME"/moc, mocp -O MOCDir="$XDG_CONFIG_HOME"/moc
monero ~/.bitmonero monerod --data-dir "$XDG_DATA_HOME"/bitmonero
most ~/.mostrc export MOST_INITFILE="$XDG_CONFIG_HOME"/mostrc
MPlayer ~/.mplayer export MPLAYER_HOME="$XDG_CONFIG_HOME"/mplayer
mtpaint ~/.mtpaint [231]
/etc/mtpaint/mtpaintrc
userINI = ~/.config/mtpaint
mypy ~/.config/mypy/config, ~/.mypy.ini, ~/.mypy_cache v0.670 [232] [233] XDG_CONFIG_HOME/mypy/config, export MYPY_CACHE_DIR="$XDG_CACHE_HOME"/mypy
MySQL ~/.mysql_history, ~/.my.cnf , ~/.mylogin.cnf export MYSQL_HISTFILE="$XDG_DATA_HOME"/mysql_history

~/.my.cnf only supported for mysql-server, not mysql-client [234]

~/.mylogin.cnf unsupported

mysql-workbench ~/.mysql/workbench You can run MySQL Workbench with the ---configdir flag, such as mysql-workbench --configdir="$XDG_DATA_HOME/mysql/workbench". The directory needs to be created manually, since MySQL Workbench default location is $HOME/.mysql/workbench .
ncurses ~/.terminfo Precludes system path searching:

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

n /usr/local/n export N_PREFIX=$XDG_DATA_HOME/n
ncmpc ~/.ncmpc ncmpc -f "$XDG_CONFIG_HOME"/ncmpc/config
Netbeans ~/.netbeans [235] netbeans --userdir "${XDG_CONFIG_HOME}"/netbeans
Node.js ~/.node_repl_history [236] export NODE_REPL_HISTORY="$XDG_DATA_HOME"/node_repl_history
npm ~/.npm, ~/.npmrc [237] export NPM_CONFIG_USERCONFIG=$XDG_CONFIG_HOME/npm/npmrc
npmrc
prefix=${XDG_DATA_HOME}/npm
cache=${XDG_CACHE_HOME}/npm
init-module=${XDG_CONFIG_HOME}/npm/config/npm-init.js
logs-dir=${XDG_STATE_HOME}/npm/logs

prefix is unnecessary (and unsupported) if Node.js is installed by nvmAUR.

opam ~/.opam [238] export OPAMROOT="$XDG_DATA_HOME/opam"

Both configuration and state data are stored in OPAMROOT, so this solution is not fully compliant.

PuTTY ~/.putty/ 9952b2d Will use $XDG_CONFIG_HOME/putty if it already exists. Creates ~/.putty if not. Prioritises $XDG_CONFIG_HOME/putty if both exist. Tested in 0.74
python-easyocrAUR ~/.EasyOCR export EASYOCR_MODULE_PATH="$XDG_CONFIG_HOME/EasyOCR"
spotdlAUR ~/.spotdl v4.0.6 (3929cae) [239] mkdir "$XDG_DATA_HOME"/spotdl
nuget ~/.nuget/packages [240] export NUGET_PACKAGES="$XDG_CACHE_HOME"/NuGetPackages
NVIDIA ~/.nv Uses XDG_CACHE_HOME if set, otherwise improperly falls back to ~/.nv instead of ~/.cache.
nvidia-settings ~/.nvidia-settings-rc [241] nvidia-settings --config="$XDG_CONFIG_HOME"/nvidia/settings
nvmAUR ~/.nvm export NVM_DIR="$XDG_DATA_HOME"/nvm
Octave ~/octave, ~/.octave_packages, ~/.octave_hist export OCTAVE_HISTFILE="$XDG_CACHE_HOME/octave-hsts", export OCTAVE_SITE_INITFILE="$XDG_CONFIG_HOME/octave/octaverc"
$XDG_CONFIG_HOME/octave/octaverc
source /usr/share/octave/site/m/startup/octaverc;
pkg prefix ~/.local/share/octave/packages ~/.local/share/octave/packages;
pkg local_list /home/<your username>/.local/share/octave/octave_packages;

The local_list option must be given an absolute path.

omnisharp-roslyn-binAUR ~/.omnisharp/ [242] [243] export OMNISHARPHOME="$XDG_CONFIG_HOME/omnisharp"
openscad ~/.OpenSCAD 7c3077b0f [244] Does not fully honour XDG Base Directory Specification, see [245]

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

packettracerAUR ~/.packettracer, ~/packettracer/ Has GUI config to change PT installation directory, ~/packettracer/ (Options > Preferences > Administrative > User Folder). This path is written to the file ~/.packettracer.
parallel ~/.parallel 20170422 export PARALLEL_HOME="$XDG_CONFIG_HOME"/parallel
pass ~/.password-store export PASSWORD_STORE_DIR="$XDG_DATA_HOME"/pass
Phive ~/.phive [246]

Also [247] and [248]

Since 0.14.5, it is possible to move the whole data directory.

export PHIVE_HOME="$XDG_DATA_HOME/phive"

Pidgin ~/.purple [249] pidgin --config="$XDG_DATA_HOME"/purple
platformio-core ~/.platformio [250] export PLATFORMIO_CORE_DIR="$XDG_DATA_HOME"/platformio
PostgreSQL ~/.psqlrc, ~/.psql_history, ~/.pgpass, ~/.pg_service.conf 9.2 [251] [252] export PSQLRC="$XDG_CONFIG_HOME/pg/psqlrc", export PSQL_HISTORY="$XDG_STATE_HOME/psql_history", export PGPASSFILE="$XDG_CONFIG_HOME/pg/pgpass", export PGSERVICEFILE="$XDG_CONFIG_HOME/pg/pg_service.conf"

It is required to create both directories: mkdir "$XDG_CONFIG_HOME/pg" && mkdir "$XDG_STATE_HOME"

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.
pyenv ~/.pyenv [253] [254] export PYENV_ROOT=$XDG_DATA_HOME/pyenv
azure-cli ~/.azure export AZURE_CONFIG_DIR=$XDG_DATA_HOME/azure
python ~/.python_history v3.13 [255] [256] [257] All history from interactive sessions is saved to ~/.python_history by default since version 3.4 and PYTHON_HISTORY since 3.13. This can still be customized the same way as in older versions (see this example), including to use a custom path or disable history saving.

PYTHON_HISTORY: export PYTHON_HISTORY=$XDG_STATE_HOME/python/history PYTHONPYCACHEPREFIX: export PYTHONPYCACHEPREFIX=$XDG_CACHE_HOME/python PYTHONUSERBASE: export PYTHONUSERBASE=$XDG_DATA_HOME/python

python-gripAUR ~/.grip export GRIPHOME="$XDG_CONFIG_HOME/grip"
python-setuptools ~/.python-eggs export PYTHON_EGG_CACHE="$XDG_CACHE_HOME"/python-eggs
racket ~/.racketrc, ~/.racket [258] export PLTUSERHOME="$XDG_DATA_HOME"/racket
rbenvAUR ~/.rbenv [259] [260] export RBENV_ROOT="$XDG_DATA_HOME"/rbenv
nodenvAUR ~/.nodenv export NODENV_ROOT="$XDG_DATA_HOME"/nodenv
readline ~/.inputrc export INPUTRC="$XDG_CONFIG_HOME"/readline/inputrc
recoll ~/.recoll export RECOLL_CONFDIR="$XDG_CONFIG_HOME/recoll"
redis ~/.rediscli_history, ~/.redisclirc export REDISCLI_HISTFILE="$XDG_DATA_HOME"/redis/rediscli_history, export REDISCLI_RCFILE="$XDG_CONFIG_HOME"/redis/redisclirc
ripgrep [261] export RIPGREP_CONFIG_PATH=$XDG_CONFIG_HOME/ripgrep/config
rlwrap ~/.*_history [262] export RLWRAP_HOME="$XDG_DATA_HOME"/rlwrap
ruby-bundler ~/.bundle 4a120d8 Pull request 3545
export BUNDLE_USER_CACHE=$XDG_CACHE_HOME/bundle
export BUNDLE_USER_CONFIG=$XDG_CONFIG_HOME/bundle/config
export BUNDLE_USER_PLUGIN=$XDG_DATA_HOME/bundle

For more info see Bundler: bundle config.

ruby-solargraphAUR ~/.solargraph/cache/ [263] export SOLARGRAPH_CACHE=$XDG_CACHE_HOME/solargraph
ruff .ruff_cache [264] export RUFF_CACHE_DIR=$XDG_CACHE_HOME/ruff
Rust#Rustup ~/.rustup [265] export RUSTUP_HOME="$XDG_DATA_HOME"/rustup
sbt ~/.sbt

~/.ivy2

[266] sbt -ivy "$XDG_DATA_HOME"/ivy2 -sbt-dir "$XDG_DATA_HOME"/sbt (beware [267])
SageMath ~/.sage export DOT_SAGE="$XDG_CONFIG_HOME"/sage
GNU Screen ~/.screenrc

~/.screen/

export SCREENRC="$XDG_CONFIG_HOME"/screen/screenrc, export SCREENDIR="${XDG_RUNTIME_DIR}/screen"
simplescreenrecorderAUR ~/.ssr/ 0.4.3 [268]

[269]

Will use $XDG_CONFIG_HOME/simplescreenrecorder/ ONLY if it already was created otherwise defaults to ~/.ssr

mv ~/.ssr "$XDG_CONFIG_HOME"/simplescreenrecorder

singularity-ceAUR ~/.singularity 3.11.4 export SINGULARITY_CONFIGDIR="$XDG_CONFIG_HOME/singularity", export SINGULARITY_CACHEDIR="$XDG_CACHE_HOME/singularity"
spacemacs ~/.spacemacs, ~/.spacemacs.d [270] [271] Move the ~/.spacemacs file.

export SPACEMACSDIR="$XDG_CONFIG_HOME"/spacemacs, mv ~/.spacemacs "$SPACEMACSDIR"/init.el

Other files need to be configured like Emacs.

SQLite ~/.sqliterc, ~/.sqlite_history 3.44.0 for the config;
history is still in the legacy place
XDG_CONFIG_HOME/sqlite3/sqliterc, export SQLITE_HISTORY=$XDG_DATA_HOME/sqlite_history
starship ~/.config/starship, ~/.cache/starship [272] (v0.2.0), [273] (v0.45.0) [274] export STARSHIP_CONFIG="$XDG_CONFIG_HOME"/starship.toml, export STARSHIP_CACHE="$XDG_CACHE_HOME"/starship
subversion ~/.subversion [275] [276][277] alias svn="svn --config-dir \"$XDG_CONFIG_HOME\"/subversion"
sudo ~/.sudo_as_admin_successful 1.9.6 [278] [279] Only present when activated at compile-time (default none). An admin_flag parameter can be used in /etc/sudoers since 1.9.6.
task ~/.task, ~/.taskrc Fully supported in version 2.6 (note $XDG_CONFIG_HOME/task/taskrc must exist, otherwise taskwarrior will offer to create sample config in legacy $HOME/.taskrc location, even if $XDG_CONFIG_HOME is set [280][281])
Local TeX Live TeXmf tree, TeXmf caches and config ~/texmf, ~/.texlive/texmf-var, ~/.texlive/texmf-config export TEXMFHOME=$XDG_DATA_HOME/texmf, export TEXMFVAR=$XDG_CACHE_HOME/texlive/texmf-var, export TEXMFCONFIG=$XDG_CONFIG_HOME/texlive/texmf-config
TeXmacs ~/.TeXmacs export TEXMACS_HOME_PATH=$XDG_STATE_HOME/texmacs
tiptopAUR ~/.tiptoprc This will still expect the .tiptoprc file.

tiptop -W "$XDG_CONFIG_HOME"/tiptop

ruby-travisAUR ~/.travis/ [282] export TRAVIS_CONFIG_PATH=$XDG_CONFIG_HOME/travis
uncrustify ~/.uncrustify.cfg export UNCRUSTIFY_CONFIG="$XDG_CONFIG_HOME"/uncrustify/uncrustify.cfg
Unison ~/.unison export UNISON="$XDG_DATA_HOME"/unison
unitsAUR ~/.units_history units --history "$XDG_CACHE_HOME"/units_history
urxvtd ~/.urxvt/urxvtd-hostname export RXVT_SOCKET="$XDG_RUNTIME_DIR"/urxvtd
Vagrant ~/.vagrant.d, ~/.vagrant.d/aliases [283] export VAGRANT_HOME="$XDG_DATA_HOME"/vagrant, export VAGRANT_ALIAS_FILE="$XDG_DATA_HOME"/vagrant/aliases
vint ~/.vintrc.yaml, .vintrc.yml, .vintrc 0f741ac2c [284] Undocumented, but the code says $XDG_CONFIG_HOME/.vintrc.yaml should work
virtualenv ~/.virtualenvs export WORKON_HOME="$XDG_DATA_HOME/virtualenvs"
Visual Studio Code ~/.vscode-oss/ [285] You can use export VSCODE_PORTABLE="$XDG_DATA_HOME"/vscode, which is not documented and might break unexpectedly.

Setting this makes the editor look for the contents of .config/Code - OSS in $VSCODE_PORTABLE/user-data.

You can also run Visual Studio with the --extensions-dir flag, such as code --extensions-dir "$XDG_DATA_HOME/vscode". This is documented and probably will not break as unexpectedly, as it is has other use cases.

VSCodiumAUR ~/.vscode-oss/ [286] [287] You can run VSCodium with the --extensions-dir flag, such as vscodium --extensions-dir "$XDG_DATA_HOME/vscode". This however won't prevent the creation of ~/.vscode-oss/ directory.
w3m ~/.w3m 26284ff [288] [289] export W3M_DIR="$XDG_STATE_HOME/w3m"
wakatime ~/.wakatime.cfg, ~/.wakatime.data, ~/.wakatime.db, ~/.wakatime.log export WAKATIME_HOME="$XDG_CONFIG_HOME/wakatime"

The directory needs to be created manually

mkdir "$XDG_CONFIG_HOME/wakatime"

wget ~/.wgetrc, ~/.wget-hsts export WGETRC="$XDG_CONFIG_HOME/wgetrc" and add the following as an alias for wget: wget --hsts-file="$XDG_CACHE_HOME/wget-hsts", or set the hsts-file variable with an absolute path as wgetrc does not support environment variables: echo hsts-file \= "$XDG_CACHE_HOME"/wget-hsts >> "$XDG_CONFIG_HOME/wgetrc"
wine ~/.wine [290] Winetricks uses XDG-alike location below for WINEPREFIX management:

mkdir -p "$XDG_DATA_HOME"/wineprefixes, export WINEPREFIX="$XDG_DATA_HOME"/wineprefixes/default

x3270AUR ~/.x3270pro, ~/.c3270pro export X3270PRO="$XDG_CONFIG_HOME"/x3270/config, export C3270PRO="$XDG_CONFIG_HOME"/c3270/config

App also creates ~/.x3270connect but this is currently unsupported.

xbindkeys ~/.xbindkeysrc xbindkeys -f "$XDG_CONFIG_HOME"/xbindkeys/config
xorg-xauth ~/.Xauthority export XAUTHORITY="$XDG_RUNTIME_DIR"/Xauthority

Note that LightDM does not allow you to change this variable. If you change it nonetheless, you will not be able to login. Use startx instead or configure LightDM. According to [291] SLiM has ~/.Xauthority hardcoded.

The SDDM Xauthority path can be changed in its own configuration files as shown below. Unfortunately, it is relative to the home directory.

/etc/sddm.conf.d/xauth-path.conf
[X11]
UserAuthFile=.Xauthority

On Wayland, overriding this may cause Xorg programs to fail to connect to the Xwayland server. For example, both kwin and mutter use a randomized name, so it cannot be set to a static value.

xinit ~/.xinitrc, ~/.xserverrc [292] export XINITRC="$XDG_CONFIG_HOME"/X11/xinitrc, export XSERVERRC="$XDG_CONFIG_HOME"/X11/xserverrc
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.
Xorg ~/.xsession, ~/.xsessionrc, ~/.Xsession, ~/.xsession-errors These can be added as part of your Xorg init script (~/.xinitrc) or Xsession start script (which will often be based on /etc/X11/Xsession).

Depending on where you have configured your $XDG_CACHE_HOME, you might need to expand the paths yourself.

# xsession start script
USERXSESSION="$XDG_CACHE_HOME/X11/xsession"
USERXSESSIONRC="$XDG_CACHE_HOME/X11/xsessionrc"
ALTUSERXSESSION="$XDG_CACHE_HOME/X11/Xsession"
ERRFILE="$XDG_CACHE_HOME/X11/xsession-errors"

Unlike most other examples in this table, actual X11 init scripts will vary a lot between installations.

z ~/.z [293] export _Z_DATA="$XDG_DATA_HOME/z"
yarn ~/.yarnrc, ~/.yarn/, ~/.yarncache/, ~/.yarn-config/ 2d454b5 [294] [295] alias yarn='yarn --use-yarnrc "$XDG_CONFIG_HOME/yarn/config"'
zsh ~/.zshrc, ~/.zprofile, ~/.zshenv, ~/.zlogin, ~/.zlogout, ~/.histfile, ~/.zcompdump, ~/.zcompcache [296] export ZDOTDIR=$HOME/.config/zsh to avoid the need of most zsh dotfiles in your home.
.config/zsh/.zshrc
HISTFILE="$XDG_STATE_HOME"/zsh/history
# Completion files: Use XDG dirs
[ -d "$XDG_CACHE_HOME"/zsh ] || mkdir -p "$XDG_CACHE_HOME"/zsh
zstyle ':completion:*' cache-path "$XDG_CACHE_HOME"/zsh/zcompcache
compinit -d "$XDG_CACHE_HOME"/zsh/zcompdump-$ZSH_VERSION

Finally, if you use zsh as a login shell and chose to rely on either of the startup files ~/.zshenv or, ~/.zprofile or, ~/.zlogin to set important enviroment variables such as ZDOTDIR, to bootstrap, there is no way around having the one file that sets ZDOTDIR be in the default location. For context, an exception is if your wider system configuration does set the ZDOTDIR enviroment variable before that.

Hardcoded

Application Legacy Path Discussion Notes
adb & Android Studio ~/.android/ Despite appearances otherwise, adb will always generate ~/.android/adbkeys, though it will try keys in ADB_VENDOR_KEYS as well.
aegisub ~/.aegisub/ [297]
alpine ~/.pinerc, ~/.addressbook, ~/.pine-debug[1-4], ~/.newsrc, ~/.mailcap, ~/.mime.types, ~/.pine-interrupted-mail alias alpine="alpine -p $XDG_CONFIG_HOME/alpine/pinerc"

In the above config file, some locations can be customized using options like newsrc-path= and address-book=.

aMule ~/.aMule [298] [299] [300]
anthy ~/.anthy [301]
Apache Directory Studio ~/.ApacheDirectoryStudio
ARandR ~/.screenlayout [302]
Arduino ~/.arduino15, ~/.jssc won't fix
arduino-cli ~.arduino15/ [303] mv ~/.arduino15 $XDG_CONFIG_HOME/arduino15

Specify the new directories used by Arduino CLI in arduino-cli.yaml as mentioned in the documentation here. alias arduino-cli='arduino-cli --config-file $XDG_CONFIG_HOME/arduino15/arduino-cli.yaml'

ASP.NET Core ~/.aspnet [304]
Avidemux ~/.avidemux6 [305]
Bash ~/.bashrc, ~/.bash_history, ~/.bash_profile, ~/.bash_login, ~/.bash_logout 108134 10431 mkdir -p "$XDG_STATE_HOME"/bash

export HISTFILE="$XDG_STATE_HOME"/bash/history

bashrc can be sourced from a different location in /etc/bash.bashrc. Specify --init-file <file> as an alternative to ~/.bashrc for interactive shells.

borgmatic ~/.borgmatic/ [306] Set borgmatic_source_directory: ~/.local/state/borgmatic in your config.yaml. This might break restore, see discussion.
Berkshelf ~/.berkshelf/
chatty ~/.chatty/ [307]
cmake ~/.cmake/ [308] Used for the user package registry ~/.cmake/packages/<package>, detailed in cmake-packages(7) § User Package Registry and the Package registry wiki page. Looks like it's hardcoded, for example in cmFindPackageCommand.cxx.
cmus ~/.config/cmus [309] [310]
Cinnamon ~/.cinnamon/ [311]
conanAUR ~/.conan/ [312] export CONAN_USER_HOME="$XDG_CONFIG_HOME" will set the directory in which .conan/ is created. It was designed to simplify CI, but can be used here too.
cryptomatorAUR ~/.Cryptomator [313]
cVim[dead link 2022-09-23 ⓘ] ~/.cvimrc [314]
darcs ~/.darcs/ [315]
dart ~/.dart, ~/.dart-tool, ~/.dartServer [316]
dbus ~/.dbus/ [317] Consider using dbus-broker, as it does not create or use this directory.
devede ~/.devedeng Hardcoded here
Dia ~/.dia/
dig ~/.digrc
dotnet-sdk ~/.dotnet/, ~/.templateengine [318]
dropbox ~/.dropbox/
Eclipse ~/.eclipse/ [319] 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)
emacs-slime ~/.slime/ [320]

[321]

equalxAUR ~/.equalx/ [322]
Fetchmail ~/.fetchmailrc
Firefox ~/.mozilla/ [323] [324]
Flatpak ~/.var/ [325] [326] won't fix
freesweep ~/.sweeprc [327]
gftpAUR ~/.gftp/ [328] Following the XDG spec is planned for gftp.
gitkrakenAUR ~/.gitkraken/ [329]
GoldenDict ~/.goldendict/ [330]
gphoto2 ~/.gphoto [331]
gramps ~/.gramps/ [332] 2022 Support XDG base directory specification (for next release Gramps 5.2 ) - Patch https://github.com/gramps-project/gramps/pull/1368
groovy ~/.groovy/
grsync ~/.grsync/ [333]
google-cloud-cliAUR ~/.gsutil/ [334]
gtk-recordMyDesktop ~/.gtk-recordmydesktop
hplip ~/.hplip/ [335]
hydrogen ~/.hydrogen/ [336]
idris ~/.idris [337]
itch-setup-binAUR ~/.itch won't fix You can move the Game install location in the app settings.
Jmol ~/.jmol/ [338]
lbdbAUR ~/.lbdbrc, ~/.lbdb/ [339]
llpp ~/.config/llpp.conf [340][dead link 2022-09-23 ⓘ] (repo was deleted) Added in 3ab86f0 but subsequently reverted in old:e253c9f1/new:e253c9f1
Java OpenJDK ~/.java/fonts [341] export _JAVA_OPTIONS=-Djava.util.prefs.userRoot="$XDG_CONFIG_HOME"/java
Java OpenJFX ~/.java/webview
jgmenu ~/.jgmenu-lockfile [342] [343]
jitsi-meetAUR ~/Downloads libjitsi#518 Download dir hardcoded to ~/Downloads rather than XDG_DOWNLOAD_DIR (from XDG user directories)
julia ~/.juliarc.jl, ~/.julia_history, ~/.julia [344] [345] The trailing :$JULIA_DEPOT_PATH is necessary. See [346]
export JULIA_DEPOT_PATH="$XDG_DATA_HOME/julia:$JULIA_DEPOT_PATH"
export JULIAUP_DEPOT_PATH="$XDG_DATA_HOME/julia"
kotlin ~/.kotlinc_history Related Konan issue: [347]
Kubernetes ~/.kube/ [348][349][350]
export KUBECONFIG="$XDG_CONFIG_HOME/kube" 
export KUBECACHEDIR="$XDG_CACHE_HOME/kube"
elan-leanAUR ~/.elan [351]
librewolfAUR ~/.mozilla

~/.librewolf

[352]
lldb ~/.lldb, ~/.lldbinit
LMMS ~/.lmmsrc.xml [353]
man-db ~/.manpath [354]
mathomatic[dead link 2024-10-12 ⓘ] ~/.mathomaticrc, ~/.matho_history History can be moved by using rlwrap mathomatic -r with the RLWRAP_HOME environment set appropriately.
MediaWiki ~/.mweval_history and ~/.mwsql_history (if $HOME is defined) If $HOME is not defined: [MediaWiki]/maintenance/.mweval_history and [MediaWiki]/maintenance/.mwsql_history.

Generated by the maintenance scripts eval.php and sql.php.

Minecraft ~/.minecraft/ won't fix
Minetest ~/.minetest/ won't fix [355]
minicom ~/.minirc.dfl Upstream has a TODO entry for supporting configuration files under ~/.config/minicom. [356]
Mono ~/.mono/ [357]
mongodb ~/.mongorc.js, ~/.dbshell [358] This Stack Overflow thread suggests a partial workaround using command-line switch --norc.
~/.netrc 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.
nim ~/.nimble [359]

[360]

Nimble will try to load ~/.config/nimble/nimble.ini at startup, set nimbleDir there. You will have to change nimblepath in the Nim compiler configuration file as well.
nmcli ~/.nmcli-history [361] Hardcoded to g_get_home_dir()[362] [363]
Networkmanager-openvpn ~/.cert/nm-openvpn [364]
nyx ~/.nyx The project is not currently maintained
ollama ~/.ollama [365] Model locations can be set with:

export OLLAMA_MODELS=$XDG_DATA_HOME/ollama/models

Source: [366]

openshot ~/.openshot_qt [367] [368]
OpenSSH ~/.ssh won't fix Assumed to be present by many ssh daemons and clients such as DropBear and OpenSSH.
palemoon ~/.moonchild productions [369]
parsec-binAUR ~/.parsec
pcsxrAUR ~/.pcsxr A -cfg flag exists, but can only be set relative to ~/.pcsxr.
perf ~/.debug Hardcoded in tools/perf/util/config.c. Commit: [370]
perl ~/.cpan, ~/perl5 [371] Perl5's CPAN expects ~/.cpan
phoronix-test-suiteAUR ~/.phoronix-test-suite [372] Partial workaround: [373]
PHP ~/.php_history [374] PHP applications can read/write a custom file with readline_read_history and readline_write_history.
portfolio-performance-binAUR ~/.PortfolioPerformance/ [375]
various shells and display managers ~/.profile
psensor ~/.psensor [376]
pulumi ~/.pulumi [377]
python-tensorflow ~/.keras [378] The issues is for tf.keras module
quilt ~/.quiltrc Fallback to /etc/quilt.quiltrc if ~/.quiltrc does not exist.
Qt Designer ~/.designer [379]
R ~/.Rprofile, ~/.Rdata, ~/.Rhistory
R_HOME_USER="$HOME/.config/R"
R_PROFILE_USER="$HOME/.config/R/profile"
R_HISTFILE="$HOME/.config/R/history"
RedNotebook ~/.rednotebook [380]
Remarkable ~/.remarkable
renderdoc ~/.renderdoc won't fix
Ren'Py ~/.renpy won't fix Recent versions respect RENPY_PATH_TO_SAVES environment variable. So you could set it to change the path for some games.
export RENPY_PATH_TO_SAVES="$XDG_DATA_HOME/renpy"
repo ~/.repoconfig [381]
rpm ~/.rpmrc ~/.rpmmacros Backlog Workaround is to use --rcfile and --macros however this come with sideeffects.
SANE ~/.sane/ scanimage creates a .cal file there
sbcl ~/.sbclrc
/etc/sbclrc
(require :asdf)
(setf sb-ext:*userinit-pathname-function*
      (lambda () (uiop:xdg-config-home #P"sbcl/sbclrc")))

Note that this requires root privileges and will change the location of ~/.sbclrc for all users. This can be mitigated by checking for an existing ~/.sbclrc inside the lambda form.

SeaMonkey ~/.mozilla/seamonkey [382]
Signal Desktop [383] Currently keeps messages in ~/.config/Signal
Snap ~/snap/ [384]
Solfege ~/.solfege, ~/.solfegerc, ~/lessonfiles [385]
SpamAssassin ~/.spamassassin
Steam ~/.steam, ~/.steampath, ~/.steampid [386] Many game engines (Unity 3D, Unreal) follow the specification, but then individual game publishers hardcode the paths in Steam Auto-Cloud causing game-saves to sync to the wrong directory.
stremioAUR ~/.stremio-server/ [387]
sts4 ~/.sts4 [388] Pass JVM arg -Dlanguageserver.boot.symbolCacheDir=$XDG_CACHE_HOME/sts4/symbolCache
python-streamlitAUR ~/.streamlit [389]
sweethome3d ~/.eteks/sweethome3d [390]
python-sympy ~/.sympy-history [391]
TeamSpeak ~/.ts3client export TS3_CONFIG_DIR="$XDG_CONFIG_HOME/ts3client"
terraform ~/.terraform.d/ [392]
texinfo ~/.infokey info --init-file "$XDG_CONFIG_HOME/infokey"
Thunderbird ~/.thunderbird/ [393]
tllocalmgr ~/.texlive
urlviewAUR ~/.urlview Use fork urlview-xdg-gitAUR instead. The fork will use XDG_CONFIG_HOME/urlview/config
viberAUR ~/.ViberPC
vimperator ~/.vimperatorrc [394] export VIMPERATOR_INIT=":source $XDG_CONFIG_HOME/vimperator/vimperatorrc"

export VIMPERATOR_RUNTIME="$XDG_CONFIG_HOME"/vimperator

visidata ~/.visidata [395]
wpa_cli ~/.wpa_cli_history
wegoAUR ~/.wegorc [396]
x2goclientAUR ~/.x2goclient alias x2goclient="x2goclient --home=$HOME/.config"
xpdf ~/.xpdfrc
xrdpAUR ~/thinclient_drives For the directory ~/thinclient_drives, you may consider editing /etc/xrdp/sesman.ini and modifying the section [Chansrv] following the example config.
XVim2 ~/.xvimrc [397]
YARD ~/.yard [398] Would accept Pull Request if anyone want to implement it.
zenmap nmap ~/.zenmap [399] [400]
zoomAUR ~/.zoom Unrecommended: setting the following variable moves the contents of .zoom but the directory itself always gets created. Moreover, it breaks some functionalities eg. being able to start a meeting. export SSB_HOME="$XDG_DATA_HOME"/zoom
zotero-binAUR ~/.zotero ~/Zotero [401] ~/Zotero default location for data can be changed from GUI: Edit -> Preferences -> Advanced -> Data Directory Location -> Custom

Tools

The tool xdg-ninjaAUR detects unwanted files/directories in $HOME which can be moved to XDG base directories. See README for examples.

The tool boxxy can be used to wrap applications which do not respect the XDG base directories and redirect any unwanted files.

The tool ephemeral can be used to link chromium/electron caches that normally live in XDG_CONFIG_HOME to locations in XDG_CACHE_HOME.

Libraries

C
libXDGdirs
libxdg-basedir
C99: Cloudef's simple implementation.
C++
xdg-utils-cxx
xdgpp
Go
adrg/xdg
go-appdir (deprecated, archived)
configdir (deprecated, abandoned)
kyoh86/xdg (deprecated, archived)
Haskell
Officially in directory since 1.2.3.0 ab9d0810ce.
xdg-basedir
JVM
Java, Kotlin, Clojure, Scala, ...
directories-jvm
Perl
File-BaseDir
Python
pyxdg
appdirs (abandoned)
platformdirs
Ruby
bkuhlmann/xdg
rubyworks/xdg (deprecated, abandoned)
Rust
directories-rs
rust-xdg
Swift
swift-xdg
Vala
Builtin support via GLib.Environment.
See get_user_cache_dir, get_user_data_dir, get_user_config_dir, etc.

Tips and tricks

Hiding unwanted directories

For directories which cannot be relocated, some desktop environments such as KDE allow you to hide them:

$ echo path >> ~/.hidden

path is the path of the file/directory, relative to the parent directory of .hidden.

See also