The XDG Base Directory Specification (commonly referred to as the XDG standard) defines where applications should store different types of user files on Linux and other Unix-like systems. It helps organize config files, data files, cache, and runtime files in a consistent and user-respecting way.
Here are the core environment variables defined by the XDG spec:
XDG_CONFIG_HOME
Purpose: User-specific configuration files
Default: $HOME/.config
Example: $HOME/.config/myapp/settings.json
XDG_DATA_HOME
Purpose: User-specific data files (non-config, non-cache)
Default: $HOME/.local/share
Example: $HOME/.local/share/myapp/database.db
XDG_CACHE_HOME
Purpose: User-specific non-essential cache files
Default: $HOME/.cache
Example: $HOME/.cache/myapp/image_cache/
XDG_STATE_HOME
(optional; newer addition)Purpose: User-specific state files (e.g. logs, history)
Default: $HOME/.local/state
Example: $HOME/.local/state/myapp/history.log
XDG_RUNTIME_DIR
Purpose: Temporary runtime files (e.g. sockets, PID files); valid only for the current session
Set by system: Typically something like /run/user/1000
Note: Must be created with correct permissions and is cleared at logout
XDG_CONFIG_DIRS
: System-wide config directories (default: /etc/xdg
)
XDG_DATA_DIRS
: System-wide data directories (default: /usr/local/share/:/usr/share/
)
Allows apps to cleanly separate user config, data, and cache
Supports multiple users and portable setups
Makes it easier to back up or clear out parts of your environment
You can write fallbacks like:
xxxxxxxxxx
import os
config_dir = os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config"))
myapp_config_path = os.path.join(config_dir, "myapp", "config.json")
A concise XDG Base Directory cheat sheet you can keep handy:
Env Var | Purpose | Default | Example Path |
---|---|---|---|
XDG_CONFIG_HOME | User-specific config files | $HOME/.config | $HOME/.config/myapp/settings.json |
XDG_DATA_HOME | User-specific data files (app data) | $HOME/.local/share | $HOME/.local/share/myapp/database.db |
XDG_CACHE_HOME | User-specific cache (rebuildable) | $HOME/.cache | $HOME/.cache/myapp/image_cache/ |
XDG_STATE_HOME | User-specific state files (logs, etc.) | $HOME/.local/state | $HOME/.local/state/myapp/history.log |
XDG_RUNTIME_DIR | Runtime files (sockets, PID files) | (set by system at login) | /run/user/1000/myapp.sock |
XDG_CONFIG_DIRS
Default: /etc/xdg
Search order for system config
XDG_DATA_DIRS
Default: /usr/local/share/:/usr/share/
Search order for system data
# Use config dir, falling back to ~/.config if unset
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}"
mkdir -p "$CONFIG_DIR/myapp"
echo "..." > "$CONFIG_DIR/myapp/settings.yml"
# Use data dir, falling back to ~/.local/share
DATA_DIR="${XDG_DATA_HOME:-$HOME/.local/share}"
mkdir -p "$DATA_DIR/myapp"
xxxxxxxxxx
import os
def xdg_path(var, default_subdir):
base = os.environ.get(var, os.path.expanduser(default_subdir))
return os.path.join(base, 'myapp')
config_dir = xdg_path('XDG_CONFIG_HOME', '~/.config')
data_dir = xdg_path('XDG_DATA_HOME', '~/.local/share')
cache_dir = xdg_path('XDG_CACHE_HOME', '~/.cache')
# e.g. ~/.config/myapp/config.yaml
config_file = os.path.join(config_dir, 'config.yaml')