Claude Code does not respect the XDG Base Directory specification
Open 💬 61 comments Opened May 31, 2025 by jennifgcrl
💡 Likely answer: A maintainer (chrislloyd, collaborator)
responded on this thread — see the highlighted reply below.
Environment
- Claude CLI version: all
- Operating System: linux
- Terminal: all
Bug Description
Claude Code writes its cache data and configs to ~/.claude.json and ~/.claude instead of following the XDG Base Directory specification. It looks like you can kinda get claude code to put some file in CLAUDE_CONFIG_DIR but the default behavior without configuration should be to follow the XDG specification.
Steps to Reproduce
install & run claude code
Expected Behavior
follows xdg specification
Actual Behavior
creates ~/.claude.json and ~/.claude directory
Additional Context
Here's what Claude Code has to say on why Claude Code should follow the XDG spec:
User Environment Respect Following XDG standards ensures Claude Code respects users' configured directory preferences rather than cluttering their home directory with dot-files. Users who have customized XDG_CONFIG_HOME, XDG_DATA_HOME, and XDG_CACHE_HOME expect all well-behaved applications to honor these settings. System Administrator Compliance In enterprise environments, system administrators often configure XDG directories to point to network storage, encrypted volumes, or specific partitions. Non-compliant applications break these carefully designed setups and create security or storage policy violations. Container and Sandboxing Compatibility Modern deployment patterns (containers, Flatpak, snap packages) rely heavily on XDG compliance for proper isolation and file system mapping. Non-compliant applications often fail or behave unpredictably in these environments. Cross-Platform Consistency While XDG originated on Linux, similar concepts exist across platforms (Windows Known Folders, macOS Application Support). Following XDG creates a foundation for consistent cross-platform behavior. Backup and Migration Simplification Users expect configuration, data, and cache to be cleanly separated. XDG compliance makes it trivial for users to backup only configuration and data while excluding cache, or to migrate settings between machines. Given Claude Code's role as a developer tool that likely stores configuration, project data, and cache files, XDG compliance is essential for professional adoption and integration into existing development workflows.
61 Comments
I confirm read/write by
~/.config/claude/CLAUDE.mdnow.Currently, I have configuration files placed only in the following directory:
I am using the following version of Claude Code:
When I check /permission, it appears that both the allow and deny settings are still active. Also, my CLAUDE.md file seems to be loading properly.
My question is as follows:
Regarding the XDG path migration, do we users need to perform any migration work or configuration changes on our end?
Looks like someone tried to fix this, but somehow the fix is partial and creates lots of issues because there wasn't a migration of existing data from one folder (
~/.claude) to another (~/.config/claude).See https://github.com/anthropics/claude-code/issues/2299#issuecomment-2993498737 for more details.
Potentially there was an issue syncing well the change of configuration folder between Claude Code and the VSCode extension.
I confirm claude read from
~/.claudewhen 2025-06-24.Please to be stable.
Please use xdg dir always.
@ncaq they were reading from ‘.config/claude’ on version 1.0.31, which was the last one I tested. Did they revert it and did a breaking change… again?!
I'm using
ln -s "$HOME/.config/claude/" "$HOME/.claude"for now to force the.config/location.A fresh new install with claude code
v1.0.34, and claude code creates the data under~/.claude! What is happening? Shouldn't it create new directory under~/.config/claudeand~/.local/share/claudefor any new installation?@chrislloyd @wolffiex: hey folks, do you think we can this super messy situation in a consistent and stable way?
As @milanglacier reported, now on
v1.0.34my Claude Code puts files in~/.claude, while I had already migrated everything to~/.config/claudeonv1.0.31.It's like every other day we have a breaking change in the folder that Claude Code stores important history and configuration, without any automatic migration of one folder to the other... this is very bad for all the users. For the 2nd time, suddenly all our settings and customizations disappear and we need to figure out where they should be.
Yeah I'm guessing they made the change and then reverted it. Anyway, Claude says:
The only way I've been able to solve this consistently is by explicitly setting
CLAUDE_CONFIG_DIRwhich seems to take precedence over everything else:it's a bit of a nitpick, but it would be nice if instead of
$XDG_CONFIG_HOMEthe creds would be stored in the keyring or at least a different directory ($XDG_RUNTIME_DIR?)pushing an api key to a config repo could be a disaster
Hi folks, I shipped (in 1.0.28) and unshipped (in 1.0.31) partial XDG support. I hear all the frustration here and I’m sorry for the thrash.
I incorrectly thought it would be a straightforward feature but didn’t anticipate migrating existing
~/.claudeconfig directories. I unshipped when we started getting reports of re-auths. This was understandably inconvenient for folks who ran the affected versions. I made the unship call because a.) there was minimal data loss (as existing~/.claudedirectories remained), and b.) the implementation didn’t properly adhere to the XDG spec (by putting session data into the config dir) and would probably have required another migration. We're also going to invest in some better tests to catch future upgrades breaking things like this.Needless to say, XDG support is on our radar but we want to do it _right._ In the meantime, I suggest using the workarounds from @JacobHayes or @joshuadavidthomas if you want to maintain the behavior from 1.0.29-31.
I've ended up getting my system in a complete mess trying to keep up with these changes.
I can work around most of it but one big issue I had was claude code reinitialising my
~/.claude.json.You only realise how vital this file is when it's already too late. None of the documentation mentions this file even though it's the place where mcp servers are configured at the project and user level.
Can someone clarify the distinction between
~/.claude.jsonand~/.claude/? e.g. why isn't the former in the latter folder? What is the intuition for what goes where?Maybe @chrislloyd you could clarify this?
The docs are not helpful (did not find any mention of
.claude.jsonin the docs at all).This is all very confusing - e.g. the
CLAUDE_CONFIG_DIRenv variable mentioned above is not menitoned in the docs: https://docs.anthropic.com/en/docs/claude-code/settings#environment-variables@bogini could you clarify, please?
Hi, I'd like to highlight this issue which is directly related to the topic here: https://github.com/anthropics/claude-code/issues/4739
## Real-World Impact: 3.8MB Configuration File Demonstrates Urgent Need for XDG Compliance
I can provide concrete evidence of why XDG compliance is critical for Claude Code usability:
### Current Disaster: Single Monolithic File
~/.claude.json### What's Inside This Monster File
### Performance Impact
### This Proves XDG Compliance is Essential
Your XDG specification request is not just about "clean directories" - it's about preventing Claude Code from
becoming unusable for active developers.
### Required XDG Structure
```bash
# Configuration (XDG_CONFIG_HOME)
~/.config/claude/config.json # MCP servers, global settings only
# Data (XDG_DATA_HOME)
~/.local/share/claude/projects/ # Project-specific data
~/project/.claude/history/ # Chat histories per project
# Cache (XDG_CACHE_HOME)
~/.cache/claude/ # Temporary files, sessions
Immediate Risk
At 3.8MB, I'm approaching the corruption threshold that affects multiple users. Every active Claude Code user will
eventually hit this problem.
XDG compliance isn't just about standards - it's about basic usability for anyone who uses Claude Code regularly.
@chrislloyd Any updates on the timeline for XDG compliance?
You have gone too far Claude. You have ignored XDG, you have inconsistent documentation, you have taken our jobs. All that I could forgive. But Claude... no
manpage?can we at least put the auth file in a directory, even if it's not XDG compliant? mounting to containers is a giant pain as a result of claude.json sitting in ~
This is so annoying, and the ~/.claude.json causes config issues for me regularly with the ~/.claude/settings.json file, especially when I have claude even create a new agent, the agent works for that session, creates in ~/.claude/agents/ dir, and then on next Claude Code restart it no longer finds the agent. The entire CC config setup is broken right now IMO.
+1 for making Claude XDG compliant. It's now a great CLI so it makes sense to start following good CLI hygiene.
PS: Weirdly, this changelog says there is support since version 1.0 but it is not working for me... https://github.com/anthropics/claude-code/blob/b4b858a11500393159bcdd64752be0e4f64864d5/CHANGELOG.md?plain=1#L509
vibed release notes
I think they added and then removed support because it was breaking things, see above in this thread
While I agree some things would be simpler by using XDG_CONFIG_HOME, I'm not sure I've seen a single user-facing problem in this thread that can't be solved in 2 minutes or less by throwing more symlinks at it. If you feel blocked on this, grab some symlinks and shoveling.
This is a STANDARD, though a non-obliged standard. If no product team care about the standard and shit on users like "you can use a symlink or whatever method xxx to DIY”… Guess why we need a STANDARD?
Dupe of #2350? I know this one is older, but #2350 also has a proposal of how to organize it with the XDG spec in mind.
This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.
issue is still occurring. @chrislloyd @wolffiex
definitely not fixed
Hi everyone, I ran into related auth persistence issues when trying to deploy CC in a VM with persistent volumes.
I believe Claude requires multiple files to avoid re-authentication:
~/.claude/.credentials.json(auth tokens)~/.config/claude/(depending on version)However, symlinking
~/.claude.json→~/.claude/.claude.jsonfails because the CLI removes the symlink and creates a regular file in its place during the write process and breaks the connection to the persistent volume.The fix, at least for containers and VMs, is to mount the entire
$HOMEdirectory instead of individual subdirectories which isn't ideal.Anecdotally, I suspect the config structures may also be contributing to sync issues when moving between the Claude Code CLI and the VS Code extension on the same machine.
any updates?
Anthropic, why don't you run Claude Code on the background to fix this issue? We would, but it's not open-source.
This seems like a very weird miss when developing a CLI tool that runs on Linux. It's concerning that this issue has been hanging out for 7.5 months already and hasn't had any official feedback or updates.
It's even more ironic when an AI Coding Agent can't have something like this fixed automatically by itself. The issues in this repo seem like the perfect opportunity to "dogfood" the product.
Claude it self suggested this layout:
| XDG Directory | Should Contain |
|---------------|----------------|
|
$XDG_CONFIG_HOME/claude/|settings.json,CLAUDE.md,commands/,agents/, MCP server definitions ||
$XDG_DATA_HOME/claude/| Installed versions/payloads, downloaded plugins ||
$XDG_STATE_HOME/claude/| Session history, per-project trust state, todos, OAuth tokens, logs ||
$XDG_CACHE_HOME/claude/| Statsig cache, any temporary/regenerable data ||
$XDG_RUNTIME_DIR/claude/| Lock files, sockets for IDE integration |Are there any updates on this issue?
Whenever I make an update, it creates ~/.local/bin/claude in my home directory.
<img width="1884" height="416" alt="Image" src="https://github.com/user-attachments/assets/f5eee5c1-2b83-4d7b-a32b-fb7ec9cb971d" />
The same issue when we install it via official script:
<img width="797" height="604" alt="Image" src="https://github.com/user-attachments/assets/0cd24716-1c9b-43c4-8d16-543e8b4bd8fa" />
And it still generates ~/.claude folder even if
CLAUDE_CONFIG_DIRis set.Also hitting this. I'm trying out an independent $CLAUDE_CONFIG_DIR, yet the
.claude.jsonstorededitorMode(weirdly, independent ofsettings.json).Windows Installer version has a strange behavior, it creates an executable file in .local/bin under UserProfile on Windows.
Yeah, the existence of a separate
~/.claude.jsonfile makes it much harder to use Claude under the Docker/dev container. It would be nice to have everything in one directory.Concrete example of the sandboxing issue mentioned above: Claude Code's config save creates
~/.claude.json.lockand~/.claude.json.tmp.*in~/, which makes it impossible to run inside Landlock-based sandboxes on Linux. These sandboxes can grant write access to a specific file but cannot allow creating new files in~/without opening the entire home directory.Details and reproduction in #30372.
The macOS side of this is messy too. Claude Code creates
~/.claude/in the home directory on Mac as well, and Claude Desktop also adds~/Library/Application Support/Claude/separately. So macOS developers end up with Claude data scattered across two different locations with no clear separation between config, cache, and auth.The
~/.claude.jsonsitting directly in$HOMEwith its lock and temp files is particularly annoying since it shows up in everylsof the home directory.I maintain ClearDisk, a free macOS menu bar tool that monitors both Claude paths along with 40+ other developer cache directories (Xcode, Docker, npm, Homebrew, etc.). It started partly because of exactly this kind of scattered config/cache problem across dev tools.
It's worth noting the optics of this one. Claude Code is a tool that writes XDG-compliant configurations for other people's software on demand. Ask it to set up a CLI tool and it'll dutifully put config in ~/.config/, data in ~/.local/share/, and cache in ~/.cache/.
It knows the spec. It can explain the spec. It can refactor an entire project to follow the spec. And then it drops .claude.json in $HOME right next to its own .claude/ directory.
This has been open since May 2025. The fix is trivial, respect XDG_CONFIG_HOME with ~/.claude/ as fallback, and move the loose root-level files inside the config directory. This is maybe 10 lines of code in a tool that generates thousands of lines a day.
Leaving this unfixed for 10+ months not so quietly says "we can't do for ourselves what we promise to do for you." That's not a great message for a product whose entire value proposition is writing good code.
Please make Claude Code store its config files and runtime files in the standard OS-specific directories (Linux: XDG Base Directory, Windows: %APPDATA%, macOS: ~/Library).
Also, it would be great to have an environment variable like Codex’s $CODEX_HOME to override the global storage root.
As much as the lack of XDG support in Linux bugs me, they do have an ENV var to set the config home:
CLAUDE_CONFIG_DIRThere is hope! We have wolffiex Adam Wolff and chrislloyd Chris Lloyd who cares enough to have a Nix config, assigned to this. The long dark night of non-XDG compliance for Anthropic may be seeing some light of XDG day.
The scattered config locations are exactly what this tool visualizes. I'm building a dashboard that shows your entire Claude Code setup — memories, skills, MCP servers, hooks — organized by scope hierarchy (global → workspace → project), aggregating from 10+ filesystem locations into one view.
You can also move items between scopes with drag-and-drop and delete duplicates, so you're not just viewing but actually managing the config across locations.
We just launched and making sense of Claude Code's config landscape is our core focus — give us a ⭐ to follow along: https://github.com/mcpware/claude-code-organizer
Looks useful but it doesn't help with proper syncing, backup or integration in the same way XDG compliance does.
LETTING THE DAYS GO BY
LET THE WATER HOLD ME DOWN
LETTING THE DAYS GO BY
WATERS FLOWING UNDER GROUND
And you may ask yourself,
Well, how did I get here?
You may find yourself
Living in a back-end stack
And you may find yourself
Behind the merge diff of a large monorepo
And you may ask yourself
"How do I work XDG?"
And you may ask yourself
"Where is my coding agent config?"
And you may tell yourself
"This is not an open-source agent!"
And you may tell yourself
"This is not good DX!"
Same as it ever was... Same as it ever was...
Letting the configs go by, let the dotfiles hold me down
Letting the configs go by, ~/.claude underground
Into the blue again, after the money's gone
Once in a lifetime, XDG compliance found
And you may tell yourself "Dario, this is not my beautiful config!"
And you may ask yourself "Where does that dotfile go?"
And you may tell wolff and lloyd "This is not good DX!"
Same as it ever was...
vibecoders can't in xdg?
Until native XDG support is added, you can redirect Claude Code's data directories using symlinks or the
CLAUDE_CONFIG_DIRenvironment variable:Workaround 1 — Symlink to XDG locations:
Workaround 2 — Use CLAUDE_CONFIG_DIR:
This moves the config directory, though some files may still land in
~/.claude.Workaround 3 — Automated cleanup in shell profile:
If you want to keep your home directory clean without breaking Claude Code:
None of these are perfect — true XDG support requires changes in Claude Code itself. But symlinks keep the actual data in spec-compliant locations while maintaining compatibility.
that is ironic that leading AI coding tool is not intelligent enough to follow established engineering standards :)
@yurukusa nice! Still, the problem with that script is that only
XDG_CONFIG_HOMEis used (dataandstateare not), right? And I think a proper solution would require a split-by-function of~/.claudeby Anthropic (our benevolent feudal lords)Confirmed via testing on 2.1.139:
CLAUDE_CONFIG_DIRscopes.claude.jsontoo — not just the.claude/folder. The binary looks for$CLAUDE_CONFIG_DIR/.claude.json, not$HOME/.claude.json. So this works as an XDG-ish workaround today:Not a real fix — default behavior is still non-compliant, and
config / cache / dataare still all under one folder rather than split across XDG's three buckets. But it unblocks the network-drive, encrypted-volume, and container use cases @jennifgcrl mentioned.Confirmation came out of a multi-context migration where I needed CLI and Desktop to read from different config dirs on the same machine — full writeup including the
.claude.jsonscoping behavior: https://github.com/MankhongGarden/claude-code-multi-context-windowsI've been following this for months and it's honestly funny how long this has been an issue 😂
Kinda funny tho, I'd assumed they'd just do a
claude, migrate this code base to conform to the XDG standard while still supporting the current layout🤣Unfortunately, such capabilities are beyond the current generation of frontier models.
Is there anyone at Anthropic who cares about this?