XDG Base Directory - ArchWiki

Jump to content

# XDG Base Directory

From ArchWiki

Related articles

- dotfiles
- XDG user directories

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 is out of date.

Reason: some of these have gotten support now meaning that the ones in hardcoded/partial needs to be checked (Discuss in Talk:XDG Base Directory)

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/
asunderAUR | `~/.asunder` `~/.asunder_album_artist` `~/.asunder_album_genre` `~/.asunder_album_title` | 2.9.0[dead link 2021-05-17—SSL error] | [12][dead link 2021-05-17—SSL error] | 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.
atuin | `~/.config/atuin` `~/.local/share/atuin` | 156893d |  |
    XDG_CONFIG_HOME/atuin/config.toml
    XDG_DATA_HOME/atuin/history.db
audacity | `~/.audacity-data/` | 3.2.0 | [13] | Uses new locations if legacy do not exist:
    XDG_CONFIG_HOME/audacity
    XDG_DATA_HOME/audacity
binwalk | `~/.binwalk` | 2051757 | [14] | `XDG_CONFIG_HOME/binwalk`
bitwarden-cli | `~/.config/Bitwarden CLI` | 1.7.1 | [15] |
    XDG_CONFIG_HOME/Bitwarden CLI
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] |
borgmatic | `~/.borgmatic/` | 1.9.0 | [17] |
btop |  | b5e709d |  | `XDG_CONFIG_HOME/btop`
byobuAUR | `~/.byobu` | 4.17 | [18] | `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 | [19] |
calcurse | `~/.calcurse` | 04162d | [20] [21] |
    XDG_CONFIG_HOME/calcurse
    XDG_DATA_HOME/calcurse
If the legacy path `~/.calcurse` is present, it will take precedence.
calibre |  |  |
catfish | `~/.config/catfish` | af65ed25 | [22] |
ccache | `~/.ccache` | 4.0 | [23] |
    XDG_CACHE_HOME/ccache
    XDG_CONFIG_HOME/ccache/ccache.conf
celestiaAUR | `~/.celestiarc` |  | [24] |
    XDG_CONFIG_HOME/celestia/celestiarc
clangd | `~/.clangd` | ad38f4b3 11.0.0 | [25] | `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.
clifmAUR | `~/.config/clifm/` | 9d6e482 |  | `XDG_CONFIG_HOME/clifm/`
Composer | `~/.composer` | 1.0.0-beta1 | [26] |
crossnote | `~/.mume` | d714a82 0.8.13 | [27] | `$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.
cryptomatorAUR | `~/.Cryptomator` | [28] |  | `$XDG_CONFIG_HOME/Cryptomator`
CUPS | `~/.cups/` | 23b1be6 | [29] |
cURL | `~/.curlrc` | 7.73.0 | [30] | `XDG_CONFIG_HOME/curlrc`
dconf |  |  |  |
Dolphin emulator | `~/.dolphin-emu` | a498c68 | [31] |
dr14_t.meter-gitAUR |  | 7e777ca | [32] | `XDG_CONFIG_HOME/dr14tmeter/`
dunst |  | 78b6e2b | [33] | `XDG_CONFIG_HOME/dunst/`
Emacs | `~/.emacs` `~/.emacs.d/init.el` | [34] 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.
Firefox | `~/.mozilla/` | 147 | [35] |
    XDG_CONFIG_HOME/mozilla/
The legacy path is used if `~/.mozilla/firefox` is present. As of Firefox 147.0.2 there is a bug when using the XDG location: `native-messaging-hosts` do not work [36].
fish |  |  |  | `XDG_CONFIG_HOME/fish/`
freesweep | `~/.sweeprc` | [37] |  |
fltk | `~/.fltk/` | 7308bcd | [38] | [39]
fontconfig | `~/.fontconfig` `~/.fonts` | 8c255fb, [40] |  | 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 | [41] [42] |
freecad | `~/.FreeCAD` | e7e2994ba 0.20.0 | [43] | 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 | [44] |
gconfAUR | `~/.gconf` | fc28caa | [45] |
ghc | `~/.ghci` | [46] |  | Supported upstream from 9.4.1 [47].
ghidra | `~/.ghidra/` | 3b0aac9 | [48] |
GIMP | `~/.gimp-x.y` `~/.thumbnails` | 60e0cfe 483505f | [49] [50] |
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`
gnuplot | `~/.gnuplot_history` | a5562b1 [51] |  |
Godot Engine | `~/.godot` | 73049d1 3.0-stable | [52] |
goobookAUR | `~/.goobookrc` | 3.5 | [53] | `XDG_CONFIG_HOME/goobookrc`
gops |  | 71c4255 |  |
GoldenDict | `~/.goldendict/` | [54] |  | `$XDG_CONFIG_HOME/goldendict/.goldendict/`
GStreamer | `~/.gstreamer-0.10` | 4e36f93 | [55] |
GTK 3 |  |  |  |
Haskell#Stack | `~/.stack` | 2.9.3 | [56] | 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 [57].
helm | `~/.helm` | 3.0.0 |  |
htop | `~/.htoprc` | 93233a6 |  | `XDG_CONFIG_HOME/htop/htoprc`
httpie | `~/.httpie` | 5af0874 | [58] |
i3 | `~/.i3` | 7c130fb |  |
i3blocks, i3blocks-gitAUR |  | [59] |  |
i3status | `~/.i3status.conf` | c3f7fc4 |  |
i3status-rust |  |  |  |
IdeaVim | `~/.ideavimrc` | 0.54.1-EAP | [60] | `XDG_CONFIG_HOME/ideavim/ideavimrc`
imagemagick |  |  |  |
Inkscape | `~/.inkscape` | 0.47 | [61] |
intellij-idea-community-edition / intellij-idea-ultimate-editionAUR | `~/.IntelliJIdeaXXXX.X` | 2020.1 | [62] |
    XDG_CONFIG_HOME/JetBrains/IntelliJIdeaXXXX.X
    XDG_DATA_HOME/JetBrains/IntelliJIdeaXXXX.X
    XDG_CACHE_HOME/JetBrains/IntelliJIdeaXXXX.X
iotop-c | `~/.config/iotop` | [63] | [64] |
ipython | `~/.ipython` | 8.0.0 | [65] | 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 |  |
josm | `~/.josm` | 11162 | [66] |
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`
latexmk (in texlive-binextra) | `~/.latexmkrc` |  |  | `XDG_CONFIG_HOME/latexmk/latexmkrc`
less | `~/.lesskey`, `~/.lesshst` | 590 full support in 598 | [67] | 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`
lftp | `~/.lftp` | 21dc400 | [68] |
lgogdownloaderAUR | `~/.gogdownloader` | d430af6 | [69] |
librewolf | `~/.librewolf` | 587de52 | [70] | The legacy path is used if ~/.librewolf is present.
luarocks | `~/.luarocks` | cd16cdd | [71] |
    XDG_CONFIG_HOME/luarocks
    XDG_CACHE_HOME/luarocks
If the legacy path `~/.luarocks` is present, it will take precedence.
mangohud |  | 65b90fc | [72] | `XDG_CONFIG_HOME/MangoHud`
mc | `~/.mc` | 1b99570 0b71156 ce401d7 | [73] |
Mercurial | `~/.hgrc` | 3540200 4.2 |  | `XDG_CONFIG_HOME/hg/hgrc`.
mesa |  | 87ab26b |  | `XDG_CACHE_HOME/mesa`
milkytracker | `~/.milkytracker_config` | eb487c5 | [74] |
mlterm | `~/.mlterm/` | 71df071 | [75] | `XDG_CONFIG_HOME/mlterm/`
mozc | `~/.mozc` | 91cc1e1 | [76] |
mpd | `~/.mpdconf` | 87b7328 |  |
mpv | `~/.mpv` | cb250d4 | [77] |
msmtp | `~/.msmtprc` | af2f409 v1.6.7+ |  | `XDG_CONFIG_HOME/msmtp/config`.
mutt | `~/.mutt` | b17cd67 | [78] |
mypaint | `~/.mypaint` | cf723b7 |  |
nano | `~/.nano/` `~/.nanorc` | c16e79b | [79] |
Neovim | `~/.nvim` `~/.nvimlog` `~/.nviminfo` | 1ca5646bb | [80] [81] |
Nestopia UE | `~/.nestopia/` | 610c008 1.51.0 | [82] |
Networkmanager-openvpn | `~/.cert/nm-openvpn` | 1.12.1 | [83] |
newsboat | `~/.newsboat` | 3c57824 | [84] | The legacy directory is used by default; if `$XDG_CONFIG_HOME/newsboat` exists, the XDG directory is used instead. Files and directories in the legacy directory should be splited manually (see newsboat(1) § FILES).
Nix | `~/.nix-channels` `~/.nix-defexpr` `~/.nix-profile` | [85] | [86] | Set `use-xdg-base-directories = true` in your `/etc/nix/nix.conf`
nmcli | `~/.nmcli-history` | 1.52.0 | [87] [88] [89] | `XDG_CACHE_HOME/nmcli-history`
node-gyp | `~/.node-gyp` | 2b5ce52a | [90] |
notmuch | `~/.notmuch-config` |  | [91] | `mkdir -p $XDG_CONFIG_HOME/notmuch/default; mv ~/.notmuch-config $XDG_CONFIG_HOME/notmuch/default/config`
np2kai-gitAUR | `~/.config/np2kai` `~/.config/xnp2kai` | 56a1cc2 | [92] |
NSS | `~/.pki` | 3.42 (da45424) | [93] | See Chromium for existing issue.
nteract-binAUR |  | 4593e72 | [94] [95] | does not recognize workarounds for ipython/jupyter
ocaml-utopAUR | `~/.utop-history` `~/.utoprc` | 2.13.0 9729963 | [96] | `XDG_STATE_HOME/utop/utop-history` `XDG_CONFIG_HOME/utop/utoprc`
OfflineIMAP | `~/.offlineimaprc` | 5150de5 | [97] | `XDG_CONFIG_HOME/offlineimap/config`
openal | `~/.alsoftrc` | 3c90ed9 |  | `XDG_CONFIG_HOME/alsoft.conf`
opentyrianAUR | `~/.opentyrian` | 39559c3 | [98] |
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
pacman | `~/.makepkg.conf` | 80eca94 | [99] |
pam-u2f | `~/.config/Yubico/u2f_keys` | ad52dd8 | [100] | `XDG_CONFIG_HOME/Yubico/u2f_keys`
panda3dAUR | `~/.panda3d` | 2b537d2 |  |
pandoc-cli | `~/.pandoc/` | 0bed0ab | [101] |
PCManFM | `~/.thumbnails` | 1.3.2 |  |
pcsx2AUR | `~/.pcsx2` | 87f1e8f a9020c6 3b22f0f 0a012ae | [102] [103] |
pnpm | `~/.pnpm-store` | [104] [105] | [106] |
poezioAUR |  |  |  |
powershellAUR |  | 6.0 |  |
ppsspp | `~/.ppsspp` | 132fe47 | [107] |
procps-ng | `~/.toprc` | af53e17 | [108] [109] |
Pry | `~/.pryrc` `~/.pry_history` | a0be0cc7 15e1fc92 e9d1be0e | [110] |
PulseAudio | `~/.pulse` `~/.pulse-cookie` | 59a8618 87ae830 9ab510a 4c195bc | [111] |
    XDG_CONFIG_DIR/pulse
    XDG_CONFIG_DIR/pulse/cookie
pyroomAUR |  |  |  |
python-autoimportAUR | `~/.config/autoimport/config.toml` | 1.2.0 | [112] | `XDG_CONFIG_HOME/autoimport/config.toml`
python-black | `~/.config/black` | 21.4b0 | [113] | `XDG_CONFIG_HOME/black`, `XDG_CACHE_HOME/black/<version>/`
python-pip | `~/.pip` | 6.0 | [114] |
python-pipx | `~/.local/pipx` | c3d8de9 | [115] | For compatibility, pipx will revert to `~/.local/pipx` if it exists. Implemented using python-platformdirs
python-poetry | `~/.poetry` | [116] | [117] |
quodlibet | `~/.quodlibet` | 3.10.0 | [118] |
qutebrowser |  |  |  |
qtile |  | fd8686e 66d704b 51cff01 | [119] | Some optional bar widgets can create files and directories in non-compliant paths, but most often these are still configurable.
rclone | `~/.rclone.conf` | 9d36258 | [120] |
retroarch |  |  |  |
ripgrep-all | `~/.cache/rga` | 963524b v0.10.3 | [121] [122] [123] |
rrAUR | `~/.rr` | 02e7d41 | [124] |
RSpec | `~/.rspec` | 5e395e2 | [125] |
rTorrent | `~/.rtorrent.rc` | 6a8d332 |  |
RuboCop | `~/.rubocop.yml` | 6fe5956 | [126] |
Ruby#RubyGems | `~/.gem` | 3.0.0 (5c6269c) | [127] |
    XDG_CONFIG_HOME/gem/gemrc
    XDG_CONFIG_HOME/irb
    XDG_DATA_HOME/gem
    XDG_DATA_HOME/rdoc
sandboxd | `~/.sandboxrc` | [128] | [129] | `XDG_CONFIG_HOME/sandboxd/sandboxrc`
scribus | `~/.scribus` | 1.5.3 |  |
scummvm | `~/.scummvmrc` `~/.scummvm/` | 7d014be | [130] | 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 | [131] |
shellcheck | `~/.shellcheckrc` | 581bcc3 |  | `XDG_CONFIG_HOME/shellcheckrc` See Shellcheck RC Files for more info.
snes9x | `~/.snes9x` | 93b5f11 | [132] | 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 | [133] |
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 | [134] | `XDG_CONFIG_HOME/sway/config`
sxhkd |  |  |  |
symfony-cliAUR | `~/.symfony5` | 5.17.1 |  | `XDG_CONFIG_HOME/symfony-cli`
systemd |  |  |  |
teeworlds | `~/.teeworlds` | [135] |  |
termite |  |  |  |
GNU#Texinfo | `~/.infokey` | 412e62fa (7.2), f76bb150 |  | `XDG_CONFIG_HOME/texinfo/infokey` Legacy path `~/.infokey` has precedence over XDG path. Texinfo will never create `XDG_CONFIG_HOME/texinfo/`.
Theming (desktop) | `~/.icons/`, `~/.themes/` | [136] |  | `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.
tig | `~/.tigrc`, `~/.tig_history` | 2.2 | [137] | `~/.local/share/tig` directory must exist, writes to `~/.tig_history` otherwise.
TigerVNC | `~/.vnc` | 1.14.0 | [138] |
tmux | `~/.tmux.conf` | 3.1 | [139] | 3.1 introduced `~/.config/tmux/tmux.conf` and in 3.2 `XDG_CONFIG_HOME/tmux/tmux.conf` was added
tmuxinatorAUR | `~/.tmuxinator` | 2636923 | [140] |
tmuxp | `~/.tmuxp` | 1.5.0 | [141] | Fixed in 1.5.2
Transmission | `~/.transmission` | b71a298 |  |
util-linux |  | 570b321 |  |
vale | `~/.vale.ini` | 3.0.0 |  |
vim | `~/.vim` `~/.vimrc` `~/.viminfo` `./.filename.swp` `./.filename.un~` `./filename~` | c9df1fb 4f04efb | [142] [143] | See Vim#Configuration for details.
vimb |  |  |  |
VirtualBox | `~/.VirtualBox` | 4.3 | [144] | Clobbers `~/.config` by writing hundreds of kilobytes of `*.log` and `*.dat` files into it.
vis | `~/.vis` | 68a25c7 d138908 | [145] |
VLC | `~/.vlcrc` | 16f32e1 | [146] |
warsow | `~/.warsow-2.x` | 98ece3f | [147] |
WeeChat | `~/.weechat` | [148] 3.2 | [149] [150] |
    XDG_CONFIG_HOME/weechat
    XDG_DATA_HOME/weechat
    XDG_CACHE_HOME/weechat
    XDG_RUNTIME_DIR/weechat
Wireshark | `~/.wireshark` | b0b53fa v2.1.0 |  |
winboat | `~/.winboat` | 16058ef | Issue 77 | `XDG_DATA_HOME/winboat-app`
wxWidgets |  | [151] |  |
XKB | `~/.xkb` |  |  | `XDG_CONFIG_HOME/xkb` only supported on Wayland [152]
xmobar | `~/.xmobarrc` | 7b0d6bf 9fc6b37 eaccf70 | [153] [154] | `XDG_CONFIG_HOME/xmobar/xmobarrc`
xmonad | `~/.xmonad/` | 40fc10b | [155] [156] | 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` |  | [157] | `$XDG_CONFIG_HOME/xonsh/rc.xsh`
xournalpp | `~/.xournalpp` | 20db937f 1.1.0 | [158] [159] |
xsel | `~/.xsel.log` | ee7b481 | [160] |
Xsettingsd | `~/.xsettingsd` | b4999f5 |  |
yapf |  | a0b51d2 | [161] | `$XDG_CONFIG_HOME/yapf/style`
Zim |  | e42b8b0 |  |
     $XDG_CONFIG_HOME/zim/preferences.conf
     $XDG_CONFIG_HOME/zim/notebooks.list
zoxide | `~/.zo` | 0.3.0 | [162] |
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`
ackAUR | `~/.ackrc` |  | [163] | `export ACKRC="$XDG_CONFIG_HOME/ack/ackrc"`
Ansible | `~/.ansible`, `~/.ansible_async` | 2.14 | [164] [165] [166] |
    export ANSIBLE_HOME="${XDG_CONFIG_HOME}/ansible"
    export ANSIBLE_GALAXY_CACHE_DIR="${XDG_CACHE_HOME}/ansible/galaxy_cache"
    export ANSIBLE_LOCAL_TEMP="${XDG_CACHE_HOME}/ansible/tmp"
    export ANSIBLE_REMOTE_TEMP="${XDG_CACHE_HOME}/ansible/tmp"
    export ANSIBLE_SSH_CONTROL_PATH_DIR="${XDG_CACHE_HOME}/ansible/cp"
    export ANSIBLE_ASYNC_DIR="${XDG_CACHE_HOME}/ansible_async"
asdf-vmAUR | `~/.asdfrc`, `~/.asdf/` |  | [167] | `export ASDF_CONFIG_FILE="${XDG_CONFIG_HOME}/asdf/asdfrc"`, `export ASDF_DATA_DIR="${XDG_DATA_HOME}/asdf"`
aspell | `~/.aspell.conf` |  | [168] | 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 | [169] | `export AWS_SHARED_CREDENTIALS_FILE="$XDG_CONFIG_HOME"/aws/credentials`, `export AWS_CONFIG_FILE="$XDG_CONFIG_HOME"/aws/config`
azure-cli | `~/.azure` |  |  | `export AZURE_CONFIG_DIR=$XDG_DATA_HOME/azure`
bash-completion | `~/.bash_completion` |  |  | `export BASH_COMPLETION_USER_FILE="$XDG_CONFIG_HOME"/bash-completion/bash_completion`
bashdbAUR | `~/.bashdbinit, ~/.bashdb_hist` |  |  | Like documented at [170], 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 [171].
bazaar | `~/.bazaar`, `~/.bzr.log` | 2.3.0 | [172] | Discussion in upstream bug states that bazaar will use `~/.config/bazaar` if it exists. The logfile `~/.bzr.log` might still be written.
bitwarden | `~/.bitwarden-ssh-agent.sock` |  | [173] | `export BITWARDEN_SSH_AUTH_SOCK="$XDG_RUNTIME_DIR"`
bogofilter-db | `~/.bogofilter` | 0.7.5 | [174] | `export BOGOFILTER_DIR="$XDG_DATA_HOME"/bogofilter`
btpd-gitAUR | `~/.btpd/` |  | [175] | `btpd -d "$XDG_DATA_HOME"/.btpd` `HOME="$XDG_DATA_HOME" btcli`
bun | `~/.bun/` |  | [176] | 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.
bup | `~/.bup/` |  |  | `export BUP_DIR="$XDG_DATA_HOME"/bup` (and move `~/.bup` there if it exists) Even if `$BUP_DIR` is not set, `$XDG_CACHE_HOME` will be used for cache.
calc | `~/.calc_history` |  |  |
    export CALCHISTFILE="$XDG_CACHE_HOME"/calc_history
Rust#Cargo | `~/.cargo` |  | [177] [178] [179] [180] | `export CARGO_HOME="$XDG_DATA_HOME"/cargo`
cataclysm-dda | `~/.cataclysm-dda` | 0.D-1 | [181] | partial support due to required compile time option
cd-bookmark | `~/.cdbookmark` |  | [182] | `export CD_BOOKMARK_FILE=$XDG_CONFIG_HOME/cd-bookmark/bookmarks` or use the fork that has native XDG support: [183]
cgdb | `~/.cgdb` | 0.8.0 | [184] [185] | 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[dead link 2026-03-12] 7551836 | [186][dead link 2026-03-12] [187] [188] | Deliberately (according to these sources) clobbers `~/.config` by writing hundreds of megabytes of cache data into it. Quite unsupported. Chromium <146 created .pki due to not setting up NSS properly even though NSS itself allowed using the XDG spec. This resulted in downstream from it not working as well (Qt WebEngine especially affecting many cases like KMail and etc.)
cinelerra | `~/.bcast5` |  | [189][dead link 2025-08-16—HTTP 404] | `export CIN_CONFIG="$XDG_CONFIG_HOME"/bcast5`
claude-codeAUR | `~/.claude`, `~/.claude.json` |  | [190] | `export CLAUDE_CONFIG_DIR="$XDG_CONFIG_HOME"/claude`
claws-mail | `~/.claws-mail` |  | [191] | `claws-mail --alternate-config-dir "$XDG_DATA_HOME"/claws-mail`
clustersshAUR | `~/.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/`.
conky | `~/.conkyrc` | 00481ee | [192] | `conky --config="$XDG_CONFIG_HOME"/conky/conkyrc`
coreutils | `~/.dircolors` |  |  | `eval $(dircolors "$XDG_CONFIG_HOME"/dircolors)`
crawl | `~/.crawl` |  |  | The trailing slash is required: `export CRAWL_DIR="$XDG_DATA_HOME"/crawl/`
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` |  | [193] | `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"`.
elan-leanAUR | `~/.elan` |  | [194] | `export ELAN_HOME="$XDG_DATA_HOME/elan"`
Electrum Bitcoin Wallet | `~/.electrum` | c121230 |  | `export ELECTRUMDIR="$XDG_DATA_HOME/electrum"`
ELinks | `~/.elinks` |  |  | `export ELINKS_CONFDIR="$XDG_CONFIG_HOME"/elinks`
elixir | `~/.mix`, `~/.hex` | afaf889 | [195] [196] | 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`
emscripten | `~/.emscripten`, `~/.emscripten_sanity`, `~/.emscripten_ports`, `~/.emscripten_cache__last_clear` |  | [197] | `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`
erlang | `~/.erlang.cookie` | [198] | [199] | Erlang does not fully conform to XDG specs, it looks for its files in `XDG_CONFIG_HOME` last. `mkdir "$XDG_CONFIG_HOME"/erlang` `mv ~/.erlang.cookie "$XDG_CONFIG_HOME"/erlang`
factorioAUR | `~/.factorio/` |  | [200] [201] | Factorio supports manually specifying data paths with a config file: [202]
    __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/` |  | [203] | `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` |  | [204] |
fzf-gitAUR | `~/.fzf.bash, ~/.fzf.zsh` |  | [205] | 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`.
GDB | `~/.gdbinit`, `./.gdb_history` | 11.1 |  | `XDG_CONFIG_HOME/gdb/gdbinit` `export GDBHISTFILE="$XDG_STATE_HOME"/gdb/history`
gemini-cli | `~/.gemini/` | 0.25.0 | [206] | `export GEMINI_CLI_HOME="$XDG_CONFIG_HOME"/gemini`
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"`
ghcup-hs-binAUR | `~/.ghcup` | [207] | [208] | `export GHCUP_USE_XDG_DIRS=true` The environment variable `GHCUP_USE_XDG_DIRS` can be set to any non-empty value. See [209].
github-copilot-cliAUR | `~/.copilot` |  | [210] | `export COPILOT_HOME="$XDG_CONFIG_HOME"/copilot`
gitsign | `~/.sigstore/root` | [211] |  | `export TUF_ROOT="$XDG_DATA_HOME"/sigstore/root`
glivAUR | `~/.glivrc` |  |  | `gliv --glivrc="$XDG_CONFIG_HOME"/gliv/glivrc`
GNU Screen | `~/.screenrc` `~/.screen/` |  |  | `export SCREENRC="$XDG_CONFIG_HOME"/screen/screenrc`, `export SCREENDIR="${XDG_RUNTIME_DIR}/screen"`
GnuPG | `~/.gnupg` |  | [212] [213] | `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.
gnuradio | `~/.gnuradio` |  | [214] | GNU Radio: `export GR_PREFS_PATH="$XDG_CONFIG_HOME"/gnuradio` GNU Radio Companion: `export GRC_PREFS_PATH="$XDG_CONFIG_HOME"/gnuradio/grc.conf`
Go | `~/go` | [215] |  | `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 [216]). `GOCACHE` is supported and defaults to `$XDG_CACHE_HOME/go-build` (see [217]).
Google Earth | `~/.googleearth` |  |  | Some paths can be changed with the `KMLPath` and `CachePath` options in `~/.config/Google/GoogleEarthPro.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
`PASSWORD_STORE_DIR` is supported only during initialization.
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` |  | [218] [219] | `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. To prevent KDE Plasma from creating this file, disable the "GNOME/GTK Settings Synchronization" background service.
hledger | `~/.hledger.journal` |  | [220] | `export LEDGER_FILE="$XDG_DATA_HOME"/hledger.journal`
Houdini | `~/houdiniMAJOR.MINOR)` |  | [221] [222] | `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` |  | [223] | `irssi --config="$XDG_CONFIG_HOME"/irssi/config --home="$XDG_DATA_HOME"/irssi`
isync | `~/.mbsyncrc` |  | [224] | `mbsync -c "$XDG_CONFIG_HOME"/isync/mbsyncrc`
Java#OpenJDK | `~/.java/.userPrefs` |  | [225] | `export _JAVA_OPTIONS=-Djava.util.prefs.userRoot="$XDG_CONFIG_HOME"/java`
jupyter | `~/.jupyter` | 5.0.0rc0 | [226] [227] | 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 [228]) python-jupyter-core >= v6.0.0: full support (via python-platformdirs) enabled by default
k9s | `~/.k9s` | 0.20.4 | [229] | `export K9SCONFIG="$XDG_CONFIG_HOME"/k9s`
KDE4 | `~/.kde`, `~/.kde4` |  | [230] | `export KDEHOME="$XDG_CONFIG_HOME"/kde` KDE4 uses `KDEHOME`. It is not recommended to set the variable for newer versions.
keychain | `~/.keychain` | [231] | [232] | `keychain --absolute --dir "$XDG_RUNTIME_DIR"/keychain`
kodi | `~/.kodi` | [233] | [234] | `KODI_DATA=$XDG_DATA_HOME/kodi`
kscriptAUR | `~/.kscript` |  | [235] | `export KSCRIPT_CACHE_DIR="$XDG_CACHE_HOME"/kscript`
ledger | `~/.ledgerrc`, `~/.pricedb` |  | [236] | `ledger --init-file "$XDG_CONFIG_HOME"/ledgerrc`
Leiningen | `~/.lein`, `~/.m2` |  | [237] | `export LEIN_HOME="$XDG_DATA_HOME"/lein` to change the m2 repo location used by leiningen look here: Leiningen#m2_repo_location
lemminxAUR | `~/.lemminx` |  | [238] | Set `xml.server.workDir` to `~/.cache/lemminx` in supported editors.
libdvdcss | `~/.dvdcss` |  | [239] | `export DVDCSS_CACHE="$XDG_DATA_HOME"/dvdcss`
libice | `~/.ICEauthority` |  | [240] | `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 |  |  | [241] | 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`
Luanti | `~/.minetest/` |  | [242] | `export MINETEST_USER_PATH="$XDG_DATA_HOME"/luanti`
lynx | `/etc/lynx.cfg` |  |  | `export LYNX_CFG="$XDG_CONFIG_HOME"/lynx.cfg`
m17n-db | `~/.m17n.d` |  | [243] |
MAME | `~/.mame` |  |  | If using Arch's mame package, `/usr/bin/mame` will be a wrapper script that automatically creates and forces use of `~/.mame`. Run `/usr/bin/mame` once to populate this directory, then you can move it to `$XDG_DATA_HOME/mame`. Edit `mame.ini` to replace all instances of `$HOME/.mame`, then you can launch MAME with `/usr/lib/mame/mame -inipath $XDG_DATA_HOME/mame`.
maptool-binAUR | `~/.maptool-rptools` |  | [244] |
    /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` |  | [245] | `export MAVEN_OPTS=-Dmaven.repo.local="$XDG_DATA_HOME"/maven/repository`, `export MAVEN_ARGS="--settings $XDG_CONFIG_HOME/maven/settings.xml"` , `mvn -gs "$XDG_CONFIG_HOME"/maven/settings.xml` and set `<localRepository>` as appropriate in settings.xml
Mathematica | `~/.Wolfram` |  |  | `export WOLFRAM_USERBASE="$XDG_CONFIG_HOME"/Wolfram` Used to be `MATHEMATICA_USERBASE`, see Upgrading from Mathematica to Wolfram.
maxima | `~/.maxima` |  |  | `export MAXIMA_USERDIR="$XDG_CONFIG_HOME"/maxima`
mednafen | `~/.mednafen` |  |  | `export MEDNAFEN_HOME="$XDG_CONFIG_HOME"/mednafen`
minikube | `~/.minikube` |  | [246] | `export MINIKUBE_HOME="$XDG_DATA_HOME"/minikube` Creates a further `.minikube` directory in `MINIKUBE_HOME` for whatever reason.
minio-client | `~/.mc` | [247] |  | `export MC_CONFIG_DIR="$XDG_CONFIG_HOME"/minio-client`
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` |  | [248] |
    /etc/mtpaint/mtpaintrc
    userINI = ~/.config/mtpaint
mypy | `~/.config/mypy/config`, `~/.mypy.ini`, `~/.mypy_cache` | v0.670 | [249] [250] | `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 [251] `~/.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` .
n | `/usr/local/n` |  |  | `export N_PREFIX=$XDG_DATA_HOME/n`
ncmpc | `~/.ncmpc` |  |  | `ncmpc -f "$XDG_CONFIG_HOME"/ncmpc/config`
ncmpcpp | `~/.ncmpcpp` `~/.lyrics` | 38d9f81 27cd86e | [252] [253] [254] | `ncmpcpp_directory` should be set to avoid an `error.log` file in `~/.ncmpcpp`. And `lyrics_directory` can be set to `~/.cache/ncmpcpp-lyrics` to avoid `~/.lyrics`.
ncurses | `~/.terminfo` |  |  | Precludes system path searching: `export TERMINFO="$XDG_DATA_HOME"/terminfo`, `export TERMINFO_DIRS="$XDG_DATA_HOME"/terminfo:/usr/share/terminfo`
Netbeans | `~/.netbeans` |  | [255] | `netbeans --userdir "${XDG_CONFIG_HOME}"/netbeans`
Node.js | `~/.node_repl_history` |  | [256] | `export NODE_REPL_HISTORY="$XDG_DATA_HOME"/node_repl_history`
nodenvAUR | `~/.nodenv` |  |  | `export NODENV_ROOT="$XDG_DATA_HOME"/nodenv`
npm | `~/.npm`, `~/.npmrc` |  | [257] | `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 nvm.
nuget | `~/.nuget/packages` |  | [258] | `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` |  | [259] | `nvidia-settings --config="$XDG_CONFIG_HOME"/nvidia/settings`
nvm | `~/.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/` | [260] | [261] | `export OMNISHARPHOME="$XDG_CONFIG_HOME/omnisharp"`
opam | `~/.opam` |  | [262] | `export OPAMROOT="$XDG_DATA_HOME/opam"` Both configuration and state data are stored in `OPAMROOT`, so this solution is not fully compliant.
openai-codex | `~/.codex/` | 5fc9fc3 | [263] | `export CODEX_HOME="$XDG_CONFIG_HOME"/codex`
openscad | `~/.OpenSCAD` | 7c3077b0f | [264] | Does not fully honour XDG Base Directory Specification, see [265] Currently it hard-codes `~/.local/share`.
packettracerAUR | `~/.packettracer`, `~/pt` |  |  | Has GUI config to change PT installation directory, `~/pt/` (Options > Preferences > Administrative > User Folder). This path is written to the file `~/.packettracer`. Log files may still be written to `~/pt/logs` regardless of this setting until the `.packettracer` file is recreated manually.
parallel | `~/.parallel` | 20170422 |  | `export PARALLEL_HOME="$XDG_CONFIG_HOME"/parallel`
pass | `~/.password-store` |  |  | `export PASSWORD_STORE_DIR="$XDG_DATA_HOME"/pass`
pdfsamAUR | `~/.openjfx` |  |  | `export _JAVA_OPTIONS=-Djavafx.cachedir="$XDG_CACHE_HOME"/openjfx`
Phive | `~/.phive` |  | [266] Also [267] and [268] | Since 0.14.5, it is possible to move the whole data directory. `export PHIVE_HOME="$XDG_DATA_HOME/phive"`
PHP | `~/.php_history` | PHP 8.4 | [269] | `export PHP_HISTFILE="$XDG_STATE_HOME"/php/history`
Pidgin | `~/.purple` |  | [270] | `pidgin --config="$XDG_DATA_HOME"/purple`
pklAUR | `~/.pkl/` |  |  | CLI flags `--settings="$XDG_CONFIG_HOME"/pkl/settings.pkl --cache-dir="$XDG_CACHE_HOME"/pkl` can be used, but must appear after the command (e.g. `pkl eval --settings(...)`)
platformio-core | `~/.platformio` |  | [271] | `export PLATFORMIO_CORE_DIR="$XDG_DATA_HOME"/platformio`
portfolio-performanceAUR | `~/.PortfolioPerformance/` |  | [272] |
PostgreSQL | `~/.psqlrc`, `~/.psql_history`, `~/.pgpass`, `~/.pg_service.conf` | 9.2 | [273] [274] | `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"`
Project Zomboid | `~/Zomboid` |  |  | You can use -cachedir="${XDG_DATA_HOME}"/Zomboid/ to change where the game files are stored. The `projectzomboid.sh` script also defines its own game data location with `GAMEDIR="${HOME}/Zomboid"`. If you use Steam, the script will be reset when the game updates, so editing it manually is not an option. But you can make a custom script that will always patch the main script if it gets restored by Steam:
    start.sh
    #!/usr/bin/env bash

    SCRIPT="$(dirname "$0")/projectzomboid.sh"
    sed 's|GAMEDIR|"${HOME}/Zomboid"|GAMEDIR="${XDG_DATA_HOME}/Zomboid"|' -i "$SCRIPT"

    exec "$SCRIPT" -cachedir="${XDG_DATA_HOME}"/Zomboid/ "$@"
Name it `start.sh` and put it where `projectzomboid.sh` is, then make Steam execute `./start.sh` instead of the main script with `./start.sh # %command%"`, note that this will also launch the game without Steam Linux Runtime.
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`.
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
pyenv | `~/.pyenv` |  | [275] [276] | `export PYENV_ROOT=$XDG_DATA_HOME/pyenv`
python | `~/.python_history` | v3.13 | [277] [278] [279] | All history from interactive sessions is saved to `~/.python_history` by default since version 3.4 and `PYTHON_HISTORY` since 3.13. For the history file, Python will not create any missing directories and only writes to the file if its directory exists. 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-easyocrAUR | `~/.EasyOCR` |  |  | `export EASYOCR_MODULE_PATH="$XDG_CONFIG_HOME/EasyOCR"`
python-gripAUR | `~/.grip` |  |  | `export GRIPHOME="$XDG_CONFIG_HOME/grip"`
python-kivy | `~/.kivy` |  |  | `export KIVY_HOME="$XDG_DATA_HOME/kivy"`
python-pylint | `~/.pylint.d` | 2.10 | [280] | Since 2.10 the data directory honors `$XDG_CACHE_HOME`. Config lookup order: `$PYLINTRC` > `~/.pylintrc` > `~/.config/pylintrc` > `/etc/pylintrc`. Both `~/.config/pylintrc` and `/etc/pylintrc` are hardcoded, ignoring `$XDG_CONFIG_HOME` and `$XDG_CONFIG_DIRS`. Workaround: `export PYLINTRC="$XDG_CONFIG_HOME"/pylint/pylintrc` (if set and existing, home directory lookup is skipped entirely).
python-setuptools | `~/.python-eggs` |  |  | `export PYTHON_EGG_CACHE="$XDG_CACHE_HOME"/python-eggs`
racket | `~/.racketrc`, `~/.racket` |  | [281] | `export PLTUSERHOME="$XDG_DATA_HOME"/racket`
rbenv | `~/.rbenv` |  | [282] [283] | `export RBENV_ROOT="$XDG_DATA_HOME"/rbenv`
readline | `~/.inputrc` |  |  | `export INPUTRC="$XDG_CONFIG_HOME"/readline/inputrc`
recoll | `~/.recoll` |  |  | `export RECOLL_CONFDIR="$XDG_CONFIG_HOME/recoll"`
redisAUR | `~/.rediscli_history`, `~/.redisclirc` |  |  | `export REDISCLI_HISTFILE="$XDG_DATA_HOME"/redis/rediscli_history`, `export REDISCLI_RCFILE="$XDG_CONFIG_HOME"/redis/redisclirc`
Ren'Py | `~/.renpy` | 7.5 | [284] | Save games are stored in `RENPY_PATH_TO_SAVES`. Data that is shared across multiple games (e.g. sequals that let you import saves from previous entries) is stored in `RENPY_MULTIPERSISTENT`.
    export RENPY_PATH_TO_SAVES="$XDG_DATA_HOME/renpy"
    export RENPY_MULTIPERSISTENT="$XDG_DATA_HOME/renpy_shared"
ripgrep |  |  | [285] | `export RIPGREP_CONFIG_PATH=$XDG_CONFIG_HOME/ripgrep/config`
rlwrap | `~/.*_history` |  | [286] | `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/` |  | [287] | `export SOLARGRAPH_CACHE=$XDG_CACHE_HOME/solargraph`
ruby-travisAUR | `~/.travis/` |  | [288] | `export TRAVIS_CONFIG_PATH=$XDG_CONFIG_HOME/travis`
ruff | `.ruff_cache` |  | [289] | `export RUFF_CACHE_DIR=$XDG_CACHE_HOME/ruff`
Rust#rustup | `~/.rustup` |  | [290] | `export RUSTUP_HOME="$XDG_DATA_HOME"/rustup`
SageMath | `~/.sage` |  |  | `export DOT_SAGE="$XDG_CONFIG_HOME"/sage`
sbt | `~/.sbt` `~/.ivy2` |  | [291] | `sbt -ivy "$XDG_DATA_HOME"/ivy2 -sbt-dir "$XDG_DATA_HOME"/sbt` (beware [292])
sdkman-binAUR | `~/.sdkman/` |  | [293] | `export SDKMAN_DIR="$XDG_DATA_HOME/sdkman"` Both configuration and data files are stored in `SDKMAN_DIR`, so this solution does not fully conform to the XDG Base Directory Specification.
simplescreenrecorderAUR | `~/.ssr/` | 0.4.3 | [294] [295] | 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` | [296] | [297] | Move the `~/.spacemacs` file. `export SPACEMACSDIR="$XDG_CONFIG_HOME"/spacemacs`, `mv ~/.spacemacs "$SPACEMACSDIR"/init.el` Other files need to be configured like Emacs.
spotdlAUR | `~/.spotdl` | v4.0.6 (3929cae) | [298] | `mkdir "$XDG_DATA_HOME"/spotdl`
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_STATE_HOME/sqlite_history`
starship | `~/.config/starship`, `~/.cache/starship` | [299] (v0.2.0), [300] (v0.45.0) | [301] | `export STARSHIP_CONFIG="$XDG_CONFIG_HOME"/starship.toml`, `export STARSHIP_CACHE="$XDG_CACHE_HOME"/starship`
subversion | `~/.subversion` |  | [302] [303][304] | `alias svn="svn --config-dir \"$XDG_CONFIG_HOME\"/subversion"`
sudo | `~/.sudo_as_admin_successful` | 1.9.6 | [305] [306][dead link 2025-08-16—HTTP 410] | 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 [307][308])
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`
Thunderbird | `~/.thunderbird/` |  | [309] | A directory `~/.cache/thunderbird` is created, containing subdirectories with the profile names, then the subdirectories `cache2`, `startupCache` and possibly others. This cache directory may also be set in about:config key browser.cache.disk.parent_directory [310].
tiptopAUR | `~/.tiptoprc` |  |  | This will still expect the `.tiptoprc` file. `tiptop -W "$XDG_CONFIG_HOME"/tiptop`
uncrustify | `~/.uncrustify.cfg` |  |  | `export UNCRUSTIFY_CONFIG="$XDG_CONFIG_HOME"/uncrustify/uncrustify.cfg`
unityhubAUR | `~/Unity` `~/Unity user templates` |  |  | Both locations can be specified in UnityHub settings. The location preferences are stored in `XDG_DATA_HOME/unityhub/secondaryInstallPath.json` and `XDG_DATA_HOME/unityhub/templatesSettings.json`.
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` |  | [311] | `export VAGRANT_HOME="$XDG_DATA_HOME"/vagrant`, `export VAGRANT_ALIAS_FILE="$XDG_DATA_HOME"/vagrant/aliases`
vint | `~/.vintrc.yaml`, `.vintrc.yml`, `.vintrc` | 0f741ac2c | [312] | 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/` |  | [313] | 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 `has other use cases`.
VMware | `~/.vmware/` |  |  | The key `refvmx.defaultVMPath` in `~/.vmware/preferences` can be used to set the default location of virtual machines.
VSCodiumAUR | `~/.vscode-oss/` |  | [314] [315] | You can run VSCodium with the `--extensions-dir` flag, such as `vscodium --extensions-dir "$XDG_DATA_HOME/vscode"`. This however will not prevent the creation of `~/.vscode-oss/` directory. You can also edit the value of `dataFolderName` in `product.json` file to `.local/share/codium` or the path you want. But this workaround will have to be applies after every update of the pacakge, so you can install vscodium-xdg-dir-patchAUR that does it automatically.
w3m | `~/.w3m` | 26284ff | [316] [317] | `export W3M_DIR="$XDG_STATE_HOME/w3m"`
wakatimeAUR | `~/.wakatime/`, `~/.wakatime.cfg` |  |  | `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_STATE_HOME/wget-hsts"`, or set the `hsts-file` variable with an absolute path as wgetrc does not support environment variables: `echo hsts-file \= "$XDG_STATE_HOME"/wget-hsts >> "$XDG_CONFIG_HOME/wgetrc"`
wine | `~/.wine` |  | [318] | 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`
xinit | `~/.xinitrc`, `~/.xserverrc` |  | [319] | `export XINITRC="$XDG_CONFIG_HOME"/X11/xinitrc`, `export XSERVERRC="$XDG_CONFIG_HOME"/X11/xserverrc`
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.
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 [320] 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.
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`.
yarn | `~/.yarnrc`, `~/.yarn/`, `~/.yarncache/`, `~/.yarn-config/` | 2d454b5 | [321] [322] | `alias yarn='yarn --use-yarnrc "$XDG_CONFIG_HOME/yarn/config"'`
z | `~/.z` |  | [323] | `export _Z_DATA="$XDG_DATA_HOME/z"`
zsh | `~/.zshrc`, `~/.zprofile`, `~/.zshenv`, `~/.zlogin`, `~/.zlogout`, `~/.histfile`, `~/.zcompdump`, `~/.zcompcache` | [324] | [325] | `export ZDOTDIR=$HOME/.config/zsh` to avoid the need of most zsh dotfiles in your home.
    "$XDG_CONFIG_HOME"/zsh/.zshrc
    # Use XDG dirs for completion and history files
    [ -d "$XDG_STATE_HOME"/zsh ] || mkdir -p "$XDG_STATE_HOME"/zsh
    HISTFILE="$XDG_STATE_HOME"/zsh/history
    [ -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 environment 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` environment 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/` | [326] |
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` | [327] [328] [329] |
Apache Directory Studio | `~/.ApacheDirectoryStudio` |  |
ARandR | `~/.screenlayout` | [330] |
Arduino | `~/.arduino15`, `~/.jssc` | will not fix |
arduino-cli | `~/.arduino15/` | [331] | `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` | [332] |
Avidemux | `~/.avidemux6` | [333] |
azote | `~/.azotebg` | [334] |
Barony | `~/.barony` | [335] |
Bash | `~/.bashrc`, `~/.bash_history`, `~/.bash_profile`, `~/.bash_login`, `~/.bash_logout` | [336] [337] | `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.
Berkshelf | `~/.berkshelf/` |  |
chatty | `~/.chatty/` | [338] |
chirp-nextAUR | `~/.chirp/` | [339] | Last developer response here
Cinnamon | `~/.cinnamon/` | [340] |
cmake | `~/.cmake/` | [341] | 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` | [342] | [343]
conanAUR | `~/.conan/` | [344] | `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.
Continue | `~/.continue/` | [345] [346] [347] |
darcs | `~/.darcs/` | [348] |
dart | `~/.dart`, `~/.dart-tool`, `~/.dartServer` | [349] |
dbus | `~/.dbus/` | [350] | 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` | [351] |
dropbox | `~/.dropbox/` | [352] |
Eclipse | `~/.eclipse/` | [353] | 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/` | [354] [355] |
equalxAUR | `~/.equalx/` | [356] |
feh | `~/.fehbg` | [357] |
Fetchmail | `~/.fetchmailrc` |  |
Flatpak | `~/.var/` | [358] [359] will not fix |
gitkrakenAUR | `~/.gitkraken/` | [360]
google-cloud-cliAUR | `~/.gsutil/` | [361] |
gphoto2 | `~/.gphoto` | [362] |
gramps | `~/.gramps/` | [363] | 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/` | [364] |
gtk-recordMyDesktop | `~/.gtk-recordmydesktop` |  |
hplip | `~/.hplip/` | [365] |
hstrAUR | `~/.hstr_blacklist`, `~/.hstr_favorites` | [366] | Recent pull request to fix this
hunspell | `~/.hunspell_default` |  | [367]
hydrogen | `~/.hydrogen/` | [368] |
idris | `~/.idris` | [369] |
itch-setup-binAUR | `~/.itch` | will not fix | You can move the Game install location in the app settings.
Java OpenJDK | `~/.java/fonts` | [370] [371] | `export _JAVA_OPTIONS=-Djava.util.prefs.userRoot="$XDG_CONFIG_HOME"/java`
Java OpenJFX | `~/.java/webview` |  |
jgmenu | `~/.jgmenu-lockfile` | [372] [373] |
jitsi-meetAUR | `~/Downloads` | libjitsi#518 | Download dir hardcoded to `~/Downloads` rather than `XDG_DOWNLOAD_DIR` (from XDG user directories)
Jmol | `~/.jmol/` | [374] |
jsignpdfAUR | `~/.JSignPdf` | [375] |
julia | `~/.juliarc.jl`, `~/.julia_history`, `~/.julia` | [376] [377] | The trailing `:$JULIA_DEPOT_PATH` is necessary. See [378]
    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: [379]
Kubernetes | `~/.kube/` | [380][381][382] |
    export KUBECONFIG="$XDG_CONFIG_HOME/kube"
    export KUBECACHEDIR="$XDG_CACHE_HOME/kube"
lbdbAUR | `~/.lbdbrc, ~/.lbdb/` | [383] |
LightDM | `~/.dmrc` | [384] | Usually made by the greeter when setting a session. If you use autologin, you can modify `lightdm.conf` as explained in LightDM#Enabling autologin
lldb | `~/.lldb`, `~/.lldbinit`, `~/.lldb/lldb-widehistory` | [385] |
llpp | `~/.config/llpp.conf` | [386][dead link 2022-09-23—HTTP 404] (repo was deleted) | Added in 3ab86f0 but subsequently reverted in old:e253c9f1/new:e253c9f1
LMMS | `~/.lmmsrc.xml` | [387] |
maliit-keyboardAUR | `~/.presage` |  | Maliit Keyboard uses an old, unmaintained library called Presage that creates `~/.presage`. In 2024, Maliit Keyboard dropped their Presage dependency but as of version 2.3.1, this has not yet been included in a release. In the meantime, compile the master branch of maliit-keyboardAUR.
man-db | `~/.manpath` | [388] |
mathomatic | `~/.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.
megacmdAUR | `~/.megaCmd/` | [389] |
Minecraft | `~/.minecraft/` | will not fix | Third-party launcher prismlauncher does not use the legacy path. Others found in Minecraft#Minecraft_mod_launchers may also use different paths.
minicom | `~/.minirc.dfl` |  | Upstream has a TODO entry for supporting configuration files under `~/.config/minicom`. [390]
mongodb | `~/.mongorc.js`, `~/.dbshell` | [391] | This Stack Overflow thread suggests a partial workaround using command-line switch `--norc`.
Mono | `~/.mono/` | [392] |
| `~/.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` | [393] [394] | 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.
nyx | `~/.nyx` |  | The project is not currently maintained
oh-my-bash-gitAUR | `~/.osh-update` |  |
Ollama | `~/.ollama` | [395] | Model locations can be set with: `export OLLAMA_MODELS=$XDG_DATA_HOME/ollama/models` Source: [396]
openshotAUR | `~/.openshot_qt` | [397] [398] |
OpenSSH | `~/.ssh` | won't fix | Assumed to be present by many ssh daemons and clients such as DropBear and OpenSSH.
palemoon | `~/.moonchild productions` | [399] |
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: [400]
perl | `~/.cpan`, `~/perl5` | [401] | Perl5's CPAN expects `~/.cpan`
phoronix-test-suiteAUR | `~/.phoronix-test-suite` | [402] | Partial workaround: [403]
various shells and display managers | `~/.profile` |  |
psensor | `~/.psensor` | [404] |
pulumi | `~/.pulumi` | [405] |
python-streamlit | `~/.streamlit` | [406] |
python-sympy | `~/.sympy-history` | [407] |
python-tensorflow | `~/.keras` | [408] | The issues is for `tf.keras` module
quilt | `~/.quiltrc` |  | Fallback to `/etc/quilt.quiltrc` if `~/.quiltrc` does not exist.
Qt Designer | `~/.designer` | [409] | Fixed in upstream, scheduled for release with QT 7 (see Discussion link)
R | `./.Rdata` `~/.Rprofile` `~/.Renviron` `~/.Rhistory` `~/.R/` |  | Partial solution (`./.Rdata` and `~/.R/licensed` remain unchanged):
    export R_PROFILE_USER="${XDG_CONFIG_HOME}/R/.Rprofile"
    export R_ENVIRON_USER="${XDG_CONFIG_HOME}/R/.Renviron"
    export R_HISTFILE="${XDG_STATE_HOME}/R/history"
    export R_MAKEVARS_USER="${XDG_CONFIG_HOME}/R/Makevars"
    export R_CHECK_ENVIRON="${XDG_CONFIG_HOME}/R/check.Renviron"
    export R_BUILD_ENVIRON="${XDG_CONFIG_HOME}/R/build.Renviron"
    export R_REPOSITORIES="${XDG_CONFIG_HOME}/R/repositories"
RedNotebook | `~/.rednotebook` | [410] |
Remarkable | `~/.remarkable` |  |
renderdoc | `~/.renderdoc` | will not fix |
repo | `~/.repoconfig` | [411] |
rpm | `~/.rpmrc` `~/.rpmmacros` | Backlog | Workaround is to use --rcfile and --macros however this come with sideeffects.
run-mailcapAUR | `~/.mailcap` |  | `export MAILCAPS="$XDG_CONFIG_HOME/mailcap"`
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` | [412] |
Signal Desktop |  | [413] | Currently keeps messages in `~/.config/Signal`
Snap | `~/snap/` | [414] |
Solfege | `~/.solfege`, `~/.solfegerc`, `~/lessonfiles` | [415] |
SpamAssassin | `~/.spamassassin` |  |
Steam | `~/.steam`, `~/.steampath`, `~/.steampid` | [416] | 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.
stellarium | `~/.stellarium/` | [417] |
Storybook | `~/.storybook/` | [418] |
stremioAUR | `~/.stremio-server/` | [419] |
sts4 | `~/.sts4` | [420] | Pass JVM arg `-Dlanguageserver.boot.symbolCacheDir=$XDG_CACHE_HOME/sts4/symbolCache`
sweethome3d | `~/.eteks/sweethome3d` | [421] |
TeamSpeak | `~/.ts3client` |  | `export TS3_CONFIG_DIR="$XDG_CONFIG_HOME/ts3client"`
terraform | `~/.terraform.d/` | [422] |
tllocalmgr | `~/.texlive` |  |
urlviewAUR | `~/.urlview` |  | Use fork urlview-xdg-gitAUR instead. The fork will use `XDG_CONFIG_HOME/urlview/config`
viberAUR | `~/.ViberPC` |  |
vimperator | `~/.vimperatorrc` | [423] | `export VIMPERATOR_INIT=":source $XDG_CONFIG_HOME/vimperator/vimperatorrc"` `export VIMPERATOR_RUNTIME="$XDG_CONFIG_HOME"/vimperator`
visidata | `~/.visidata` | [424] |
wegoAUR | `~/.wegorc` | [425] |
wpa_cli | `~/.wpa_cli_history` |  | `alias wpa_cli='HOME=$XDG_STATE_HOME wpa_cli'`
x2goclientAUR | `~/.x2goclient` |  | `alias x2goclient="x2goclient --home=$HOME/.config"`
xpdf | `~/.xpdfrc` | [426] |
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` | [427] |
yabridge-binAUR | `~/.vst/yabridge/`, `~/.vst3/yabridge/`, `~/.clap/yabridge/` | will not fix |
YARD | `~/.yard` | [428] | Would accept Pull Request if anyone want to implement it.
zenmap | `~/.zenmap` | [429] [430] |
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` | [431] | `~/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.Directories

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 (old spec 0.6)
  File-XDG

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

- GNOME Goal: XDG Base Directory Specification Usage
- Rob Pike: "Dotfiles" being hidden is a UNIXv2 mistake.
- systemd-path(1)
- file-hierarchy(7)
- Grawity's notes on dotfiles.
- Grawity's notes on environment variables.
- ploum.net: Modify Your Application to use XDG Folders.
- The PCGamingWiki attempts to document whether or not Linux PC games follow the XDG Base Directory Specification.

Categories:

- Freedesktop.org
- Configuration files
- Development

Hidden categories:

- Pages or sections flagged with Template:Out of date
- Pages or sections flagged with Template:Expansion
- Pages with dead links

XDG Base Directory
Add topic