Skip to content

Adhere to XDG Base Desktop Specification on Linux platforms #1980

Open

Description

@offsetcyan

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)

Activity

  1. bolinfest commented on Aug 8, 2025

    @bolinfest
    Collaborator

    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.

  2. offsetcyan commented on Aug 8, 2025

    @offsetcyan
    Author

    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?

  3. bolinfest commented on Aug 8, 2025

    @bolinfest
    Collaborator

    @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.

  4. 99991 commented on Aug 11, 2025

    @99991

    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.

  5. offsetcyan commented on Aug 11, 2025

    @offsetcyan
    Author

    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.

  6. 0xdevalias commented on Aug 16, 2025

    @0xdevalias
  7. DanielZlotin commented on Aug 31, 2025

    @DanielZlotin

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

  8. bolinfest commented on Sep 3, 2025

    @bolinfest
    Collaborator

    @DanielZlotin do you have repro steps?

    The only thing that could be remotely related in recent history is #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.

  9. DanielZlotin commented on Sep 3, 2025

    @DanielZlotin

    @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

  10. added a commit that references this issue on Sep 4, 2025
  11. bolinfest commented on Sep 4, 2025

    @bolinfest
    Collaborator

    @DanielZlotin are you sure it isn't being picked up? I believe it should:

    fn load_instructions(codex_dir: Option<&Path>) -> Option<String> {
    let mut p = match codex_dir {
    Some(p) => p.to_path_buf(),
    None => return None,
    };
    p.push("AGENTS.md");
    std::fs::read_to_string(&p).ok().and_then(|s| {
    let s = s.trim();
    if s.is_empty() {
    None
    } else {
    Some(s.to_string())
    }
    })
    }

  12. aofei commented on Sep 27, 2025

    @aofei
    Contributor

    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/
    
  13. 0xdevalias commented on Oct 1, 2025

    @0xdevalias

    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 #143 (comment)

    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 #143 (comment)

    (With my far less detailed personal opinion that links to some other sources in this comment: #143 (comment))

  14. John-Gee commented on Dec 27, 2025

    @John-Gee

    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. ;)

  15. added
    CLIIssues related to the Codex CLI
    and removed
    agentIssues related to the core agent loop
    on Dec 28, 2025
  16. mmgeorge commented on Jan 19, 2026

    @mmgeorge

    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.

  17. added
    agentIssues related to the core agent loop
    and removed
    CLIIssues related to the Codex CLI
    on Feb 4, 2026
  18. added a commit that references this issue on Feb 9, 2026
  19. Bad3r commented on Feb 10, 2026

    @Bad3r

    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.

  20. lhanson commented on Feb 28, 2026

    @lhanson

    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.

  21. haydonryan commented on Mar 1, 2026

    @haydonryan

    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

  22. timshadel commented on Mar 19, 2026

    @timshadel

    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.

  23. datalogics-kam commented on Mar 31, 2026

    @datalogics-kam

    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.

  24. afternoon commented on Jul 13, 2026

    @afternoon

    $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!

  25. offsetcyan commented on Jul 14, 2026

    @offsetcyan
    Author

    $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.

  26. justauserid commented on Aug 20, 2026

    @justauserid

    $XDG_CONFIG_HOME is unset on my Mac also

    Yeah. As much as codex/opencode/etc should not have done this whole charade of dumping inside ~/.config (and then hide behind "oh, mac bad"), mac indeed does these things in a way that is just incompetent.

    Also, probably these well meaning devs were not yet aware that mac does have ~/Library/ just for such dumping. You never know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agentIssues related to the core agent loopenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions