# How Setting XDG_CONFIG_HOME Affects Ponytail's Configuration File Lookup Path

> Discover how setting XDG_CONFIG_HOME changes Ponytail's config file lookup path. Learn how to manage your configuration effectively for this powerful tool.

- Repository: [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail)
- Tags: how-to-guide
- Published: 2026-09-12

---

**Setting `XDG_CONFIG_HOME` overrides Ponytail's default configuration directory, forcing the application to read and write [`config.json`](https://github.com/DietrichGebert/ponytail/blob/main/config.json) from `$XDG_CONFIG_HOME/ponytail/` instead of the standard platform-specific fallback locations.**

Ponytail adheres to the **XDG Base Directory Specification** for locating its configuration files. When the environment variable `XDG_CONFIG_HOME` is defined, Ponytail redirects all configuration operations to a subdirectory within that path, bypassing the conventional default directories. This behavior is implemented consistently across both the JavaScript and Python entry points in the DietrichGebert/ponytail repository.

## How XDG_CONFIG_HOME Overrides the Default Config Location

When `XDG_CONFIG_HOME` is present in the environment, Ponytail constructs its configuration directory by appending `/ponytail` to the variable's value.

In [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js), the lookup logic explicitly checks for this variable:

```js
if (process.env.XDG_CONFIG_HOME) {
  return path.join(process.env.XDG_CONFIG_HOME, 'ponytail');
}

```

Similarly, the Python entry point in [`__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/__init__.py) mirrors this implementation:

```python
if os.environ.get("XDG_CONFIG_HOME"):
    return Path(os.environ["XDG_CONFIG_HOME"]) / "ponytail"

```

In both cases, Ponytail expects to find [`config.json`](https://github.com/DietrichGebert/ponytail/blob/main/config.json) inside this directory. If the directory or file does not exist, Ponytail creates it within the `XDG_CONFIG_HOME` hierarchy.

## Fallback Behavior When XDG_CONFIG_HOME Is Unset

If `XDG_CONFIG_HOME` is undefined, Ponytail falls back to platform-specific defaults according to the XDG specification:

- **Unix-like systems (Linux/macOS):** `$HOME/.config/ponytail`
- **Windows:** `%USERPROFILE%\AppData\Roaming\ponytail`

This fallback ensures cross-platform compatibility while respecting standard conventions for user-specific configuration data.

## Practical Implementation Examples

You can verify or utilize this behavior across different environments.

### Override in a Shell Session (Unix/Linux)

```sh
export XDG_CONFIG_HOME=$HOME/.custom-config
ponytail

```

Ponytail now reads and writes to `$HOME/.custom-config/ponytail/config.json`.

### Override in Node.js

```js
process.env.XDG_CONFIG_HOME = '/tmp/ponytail-test';
const { loadConfig } = require('ponytail/hooks/ponytail-config');
// Configuration loads from /tmp/ponytail-test/ponytail/config.json
console.log(loadConfig());

```

### Override in Python

```python
import os
os.environ["XDG_CONFIG_HOME"] = "/tmp/ponytail-test"
from ponytail import some_module

# Configuration resolves to /tmp/ponytail-test/ponytail/config.json

print(some_module.get_config())

```

## Configuration Directory Structure

Regardless of how the path is determined, Ponytail expects this directory layout:

```

$XDG_CONFIG_HOME/
└── ponytail/
    └── config.json

```

If using the default fallback on Linux without `XDG_CONFIG_HOME` set, this becomes:

```

$HOME/.config/
└── ponytail/
    └── config.json

```

## Summary

- **Setting `XDG_CONFIG_HOME`** redirects Ponytail to use `$XDG_CONFIG_HOME/ponytail/` as the configuration directory.
- **Both JavaScript and Python implementations** check `XDG_CONFIG_HOME` before falling back to defaults, as implemented in [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js) and [`__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/__init__.py).
- **Fallback paths** are `$HOME/.config/ponytail` on Unix systems and `%USERPROFILE%\AppData\Roaming\ponytail` on Windows.
- **The lookup is immediate** upon process start; changing the environment variable requires restarting the Ponytail process to take effect.

## Frequently Asked Questions

### Where does Ponytail look for config.json if XDG_CONFIG_HOME is not set?

If `XDG_CONFIG_HOME` is undefined, Ponytail uses the XDG default locations: `$HOME/.config/ponytail` on Linux and macOS, and `%USERPROFILE%\AppData\Roaming\ponytail` on Windows. This fallback logic is hardcoded in both [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js) and [`__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/__init__.py).

### Can I use a custom config directory without setting XDG_CONFIG_HOME globally?

Yes. You can set the variable for a single command: `XDG_CONFIG_HOME=/tmp/my-config ponytail`. Alternatively, set it programmatically before importing Ponytail modules in Node.js or Python, as shown in the implementation examples above.

### Does Ponytail create the config directory automatically?

Yes. If the `ponytail` subdirectory does not exist within the determined configuration directory (whether from `XDG_CONFIG_HOME` or the fallback), Ponytail creates it along with [`config.json`](https://github.com/DietrichGebert/ponytail/blob/main/config.json) when writing configuration data.

### Is the XDG_CONFIG_HOME behavior tested in the Ponytail test suite?

Yes. The repository includes unit tests in [`tests/hooks.test.js`](https://github.com/DietrichGebert/ponytail/blob/main/tests/hooks.test.js) that verify configuration loading respects `XDG_CONFIG_HOME`, and [`tests/uninstall.test.js`](https://github.com/DietrichGebert/ponytail/blob/main/tests/uninstall.test.js) demonstrates using temporary `XDG_CONFIG_HOME` values during test cleanup routines.