Adhere to XDG Base Desktop Specification on Linux platforms

Open 💬 21 comments Opened Aug 8, 2025 by offsetcyan
💡 Likely answer: A maintainer (bolinfest, collaborator) responded on this thread — see the highlighted reply below.

The user's home directory is not the place to dump program data, and for future cross-platform compatibility handling this would be inappropriate. Currently Codex stores its data in ~/.codex (modulated by a custom CODEX_HOME environment variable), however Linux has a popular specification for where to place files of various types (link). In Codex's case, $XDG_CONFIG_HOME/codex/ would be suitable. (more info)

View original on GitHub ↗

21 Comments

bolinfest collaborator · 11 months ago

XDG_CONFIG_HOME on Mac (I know you're asking about Linux) is "$HOME/Library/Application Support", which is annoying, as it contains spaces and makes all sorts of commands hard to copy/paste.

The default of $HOME/.config on Linux is more sane, but then every documentation example is more complex.

We decided to go with ~/.codex instead, but we do honor CODEX_HOME, so you can set that to whatever you like.

offsetcyan · 11 months ago

A user needing to add a custom environment variable to their session for every application that (not unreasonably) prefers special behaviour to save development effort would lead to a very uncooperative ecosystem and tedium on part of users. Would a PR for the desired behaviour in this and #142 be considered?

bolinfest collaborator · 11 months ago

@offsetcyan as noted:

The default of $HOME/.config on Linux is more sane, but then every documentation example is more complex.

Mainly for that reason, no, I would not consider a PR that would change the default to $XDG_CONFIG_HOME/codex on Linux.

It would also break existing users at this point.

99991 · 11 months ago

This is a common mistake. Here you can track the progress of VS Code, Claude Code and Aider as they fix the same issue.

XDG_CONFIG_HOME on Mac (I know you're asking about Linux) is "$HOME/Library/Application Support", which is annoying, as it contains spaces and makes all sorts of commands hard to copy/paste.

Thus, Linux users suffer again for Apple's sins.

offsetcyan · 11 months ago
It would also break existing users at this point.

This kind of change can be implemented in a backwards-compatible way by checking for the existence of CODEX_HOME and ~/.codex in that order, then following the XDG spec if neither were specified.

0xdevalias · 11 months ago
DanielZlotin · 10 months ago

There seems to be a regression in latest version no longer respecting the $CODEX_HOME env var

bolinfest collaborator · 10 months ago

@DanielZlotin do you have repro steps?

The only thing that could be remotely related in recent history is https://github.com/openai/codex/pull/2308.

Though note that many of our integration tests rely on CODEX_HOME being honored, so it feels unlikely that it could be _completely_ broken.

DanielZlotin · 10 months ago

@bolinfest the real issue is AGENTS.md and instructions.md stopped getting picked up from CODEX_HOME, so maybe the env does work in other contexts

bolinfest collaborator · 10 months ago
aofei contributor · 9 months ago

Experience shows that it's almost impossible to convince anyone who isn't a CLI die-hard to learn about the XDG Base Directory Specification, especially those who live comfortably in macOS. Until one day, they suddenly notice their $HOME overflowing with all kinds of so-called "home directories" left behind by every piece of software they've ever installed. The clutter finally becomes unbearable.

That's when they stumble upon the XDG Base Directory Specification, and start looking for tools like xdg-ninja to free their $HOME. But soon, they discover that some software simply refuses to follow the spec. So they head to those projects' issue trackers, file proposals, and get rejected. Because, as it turns out, the maintainers are going through the very same awakening themselves.

Grumble aside, this is what I did for Codex:

export CODEX_HOME=~/.cache/codex
mkdir -p $CODEX_HOME ~/.config/codex
touch ~/.config/codex/config.toml
ln -s ~/.config/codex/config.toml $CODEX_HOME/
0xdevalias · 9 months ago
especially those who live comfortably in macOS

More discussion (including recent) about this on macOS here:

Notably recently:

In the referenced apple doc "app" refers to packaged macos Apps (living in /Applications). They distinguish in the docs between Apps and CLI tools, and here the universal way that also CLI tools that Apple packages by default uses is indeed also the ~/.config dir. So for CLI tools Application Support is not the correct location. For more info: https://becca.ooo/blog/macos-dotfiles/ _Originally posted by @ponychicken in https://github.com/openai/codex/issues/143#issuecomment-3343504429_

And:

There was a good discussion about that article (which I disagree with the conclusions of wholly and totally) on Lobste.rs: https://lobste.rs/s/iv17mx/macos_dotfiles_should_not_go_library _Originally posted by @offsetcyan in https://github.com/openai/codex/issues/143#issuecomment-3344411658_

(With my far less detailed personal opinion that links to some other sources in this comment: https://github.com/openai/codex/issues/143#issuecomment-3193951902)

John-Gee · 6 months ago
We decided to go with ~/.codex instead, but we do honor CODEX_HOME, so you can set that to whatever you like.

If you respect a single variable then it is not enough to respect the spec. If you won't accept to change the default, which I think is ok not everyone will necessary prefer the xdg, couldn't you at least support the xdg secondarily, and if needed with an unsupported "Here be dragons" style? Of course having to support the split of dirs that you don't care about isn't very fun, but in the age of agentic tools it doesn't seem like the worse thing. ;)

mmgeorge · 6 months ago

As a windows user I also use XDG_CONFIG_HOME since all of my dev stuff is on a Dev Drive (ReFS). The default filesystem in windows is painfully slow. Most stuff honors this on windows as well.

Bad3r · 5 months ago
We decided to go with ~/.codex instead, but we do honor CODEX_HOME, so you can set that to whatever you like.

this is no longer correct for ~/.agents it's hardcoded in the loader at codex-rs/core/src/skills/loader.rs:196 and codex-rs/core/src/skills/loader.rs:199.

lhanson · 4 months ago

Just coming across this as I start using Codex. Arguments about additional complexity or breaking existing users have been made and overcome on numerous more popular projects, kind of surprised to still keep seeing them.

haydonryan · 4 months ago

It is a pet peeve that apps think they can throw config into the home folder on linux. I shouldn't need to set an environment variable (polluting the env instead of $HOME is just as bad) to force the correct behavior on linux.

Can't you just add a check and have it set the location internally within the app?
eg:
if directory_exists ($XDG_CONFIG_HOME/codex) codexhome = $XDG_CONFIG_HOME/codex
else if ($HOME/.codex) exists codexhome = $HOME/.codex

Then i could just move the folder and it would _just work_
There are a ton of us in the community who are passionate about this - keep getting issue logged - please fix

timshadel · 4 months ago

The XDG base directory standard exists to separate categories of user-managed files that most apps otherwise dump into one hidden directory. Its purpose is operational, not ideological: make systems easier to understand, back up, sync, inspect, clean, migrate, and automate.

The main divisions are:

  • Config: settings the user may want to edit, track, template, or sync across machines.
  • Data: durable user/application data that should persist but is not “settings”.
  • State: local, durable but reconstructable runtime state such as histories, indexes, session metadata, queues, and databases.
  • Cache: disposable data that can be regenerated.
  • Runtime: ephemeral per-login/process data like sockets, locks, and temp IPC files.

Why that matters:

  • These files have different lifecycles.
  • They have different backup/sync value.
  • They have different privacy and sensitivity profiles.
  • Users often want to manage them with different tools and policies.

Examples:

  • config.toml and AGENTS.md are usually “config”.
  • Session transcripts, sqlite state, model caches, and command history are usually “state”.
  • Downloaded indexes and derived caches are usually “cache”.
  • Auth tokens may be config or state depending on how the app treats them, but they should at least be separable from caches.

An app does not need to “adopt XDG” wholesale to honor these principles. It can just expose seams:

  • Separate env vars or flags for config, data, state, and cache roots.
  • Separate defaults internally even if the app still presents one umbrella home.
  • Per-file overrides for especially important artifacts like config, agents instructions, sessions, and history.
  • Clear docs saying which files are safe to sync, back up, delete, or ignore.

That gives users the key benefit: they can administer their systems intentionally. A macOS user might map those seams to ~/Library/Application Support, ~/Library/Caches, and local state conventions. An XDG-oriented user might map them to XDG_CONFIG_HOME, XDG_STATE_HOME, and XDG_CACHE_HOME. The app does not need to pick a philosophy; it just needs to stop pretending all files are the same kind of thing.

There is also a direct developer value pitch here. If the Codex team is itself building with agents, clear file categories reduce internal entropy: agents and humans can both follow simple rules about where new files belong, instead of gradually scattering configs, caches, state, and logs into one catch-all directory. That lowers maintenance cost, makes reviews easier, reduces accidental coupling between unrelated persistence concerns, and gives the codebase cleaner seams for testing, cleanup, migration, and future platform support. In practice, this is less about “supporting XDG” than about encoding a sane storage model so the software stays coherent as it grows.

A practical minimal design is:

  • One default app home for users who do not care.
  • Optional overrides like APP_CONFIG_DIR, APP_STATE_DIR, APP_CACHE_DIR.
  • Docs that classify each file the app writes.

That is enough to respect the distinction without forcing a platform-wide standard onto anyone.

datalogics-kam · 3 months ago
XDG_CONFIG_HOME on Mac (I know you're asking about Linux) is "$HOME/Library/Application Support", which is annoying, as it contains spaces and makes all sorts of commands hard to copy/paste.

Where are you seeing this?

env | grep XDG

returns no data at all on my Mac. Using ps shows that XDG variables are not set for Codex.app either. Indeed, if I look at the default directory for $XDG_CONFIG_HOME, which is $HOME/.config, it's full of configs for such programs as git, gh, ngrok, uv....

Any program that uses XDG on my Mac acts just like if it was on Linux.

If some library thinks that XGD_CONFIG_HOME defaults to Application Support, then that library isn't following the XDG Base Directory Specification.

afternoon · 7 days ago

$XDG_CONFIG_HOME is unset on my Mac also (macOS 15.7.7). Typically other apps write to $HOME/.config, e.g. fish, helix, git, gh, nvim, zed, goose and so many more!

offsetcyan · 6 days ago
$XDG_CONFIG_HOME is unset on my Mac also (macOS 15.7.7). Typically other apps write to $HOME/.config, e.g. fish, helix, git, gh, nvim, zed, goose and so many more!

Yes, because you haven't set it and macOS doesn't encourage it by default (yet). .config should be considered a fallback from an unset $XDG_CONFIG_HOME.