I took a look in my own ~/.config directory and it’s interesting to see that while most programs use it correctly, Chromium, Signal (which is largely just Chromium), and pulseaudio throw a bunch of crap in that directory which isn’t configuration at all, like caches, databases, and crash reports.
Upon further investigation, this is even stupider than I thought; Chromium is writing to ~/.config despite the fact that I’ve explicitly overridden $XDG_CONFIG_HOME to be $HOME; nice going Google.
(Note for Go users: Go’s os.UserConfigDir is just a hardcoded $HOME/.config (literally so unhelpful))
(Note for Go users: Go’s os.UserConfigDir is just a hardcoded $HOME/.config (literally so unhelpful))
Here is the source for os.UserConfigDir — AFAICT it is not hard coded to $HOME/.config, that’s a fallback case. Am I missing something?
no, you’re absolutely correct.
Corrected. I don’t know why I had false data on that.
Also please stop doing this especially on Windows - my user/documents directory is for… documents not useless config files I’ll never touch.
The correct place on Windows (the world’s most widely used operating system so - not one to ignore by any stretch) is %APPDATA%. And if you for some reason don’t want to support syncing configuration between devices, then %LOCALAPPDATA% is the one. Though most of the time there’s no reason not to support syncing.
*the world’s most widely used desktop PC operating system
Just to clarify: the purpose of %LOCALAPPDATA% is, well, any mutable data the app doesn’t want to sync. I don’t use that folder because I “don’t want to support syncing”, but rather for things like caches and (my favorite) machine-specific settings, such as OAuth tokens or settings overrides. The former maps nicely to ~/.cache in the XDG model, but the latter I use in all my hobby stuff so I can just rely on my roaming profile for all my core changes (no need for git syncing dotfiles!), but can easily do custom overrides when needed (maybe a different font set, a different way to handle auth, whatever). That’s obviously something apps need to opt into, but I’ve seen it reasonably frequently in well-written Windows tools.
I’ve always wondered what the difference between those directories was. There’s also a third directory, ~/AppData/LocalLow that not many applications seem to use. What’s the purpose of that one?
No direct equivalent I can think of on Linux. Programs that need to run in a low integrity level are restricted to reading and writing from certain locations; LocalLow is their equivalent of Local (the idea being to keep those programs from accessing any data they’re not supposed to, including other apps’ settings). I’ve never actually written anything that needed that, so the only example I even know of that qualifies are old versions of IE, and modern version of IE and I believe Chrome (and probably all Blink browsers) running in incognito mode. The closest equivalent I could think of would probably be e.g. a version of snap where, rather than using AppArmor to let you access only ~/.config/<app name>, you instead got a totally separate ~/.config-snap or something.
Indeed. My pet peeve is video games that dump save game directories in Documents. Windows has a whole system for this with Known Folders, one of which is FOLDERID_SavedGames. It’s right there! Why does almost nobody use it? Ended up writing my own tool to mass move/junction/hide save game folders to reclaim my Documents folder from all the junk.
Basically, it’s because users have a hard time finding it, which causes pain when doing tech support. ~\AppData is hidden, and while ~\Saved Games isn’t, it also isn’t in the My Computer/This PC screen. I think the compromise a lot of games have adopted, of ~\Documents\My Games, is a good one.
If you see anything wrong (objectively, subjectively) with the text do say. and if you have a suave but sexy (think, Sean Connery as James Bond) CSS theme I can import as a single line of HTML or something do share (thank you @AndyKluger).
Regarding CSS, maybe https://watercss.kognise.dev/
The link block text looks like white-on-white for me
Does it look better now?
HTML tables would be easier to read than ASCII, and would scale to the display.
Wholehearted agreement with the content. Did notice “stanardised” in the opening paragraph.
Disagree on the recommendations for macOS. I want my caches and config for GUI apps to go in ~/Library – but please follow XDG for CLI apps!
Honest question — why should GUI apps and CLI apps behave differently?
Good question. For me I think it’s for a number of reasons:
Found some more rationales on why to use XDG on Mac in this stack overflow reply.
Interesting. (I definitely interact with ~/Library on a regular basis!)
My mental model of config/cache/etc. directories has always been that they’re defined by, and specific to, the operating system. So, for example, my dotfiles live in a single repo, but they’re “installed” (basically, symlinked) on a macOS host with one script, and on a Linux host with a different script.
I agree with that in principle but I don’t know much about MacOS wrt darwin-exclusive CLI applications. My understanding is a lot of those applications are paid and come with GUI wrappers, which suggests an adherence to the ecosystem.
I’m not sure about Darwin-exclusive things, but my general preference is:
NSUserDefaults is automatically stored in the right location (and supports multiple scopes with inheritance between them and other nice things).
Yeah most of the CLI apps are switching to XDG on macOS which is great – as a developer I want them in a central, yet easily accessible location that can be configured easily with a dotfile manager (incredibly frustrating that Apple itself still hardcodes stuff to be directly in the home directory – stuff like ~/.lldb/lldb-widehistory, and ~/.swiftpm).
For GUI apps which are configured from a dialogue box or something, then putting them in the system location makes sense. However if those are calling out to say, git, then they’ll still respect the config put in the standard XDG location (examples of this are Gitup and Tower).
There’s a bunch of railing against this problem in a bunch of XDG/XDG-adjacent libraries (at least in the rust world) - that those libraries should allow XDG to take effect on macOS regardless of Apple’s guidelines.
The right way IMO to fix this is to provide some sort of “I want to use XDG” config option. Doing so for each app is a problem, so this needs to be a user configuration file / variable for this, but it’s difficult to work out the chicken / egg problem for this. Does it belong in ~/Library/Application Support/XDG perhaps?
Yeah… one issue I sometimes run into is how do get GUI-based development tools to load a consistent environment to what I use in my shell. I have a bunch of hacks applied from the arch wiki to get various non-compliant CLI tools to use XDG, but every so often they get called when the environment variables haven’t been loaded, which messes things up again. Not sure if I should be using launchctl or something.
Really wish Apple themselves would provide clarity on this, but as I mentioned, they seem to be be continuing to hard-code things to the home directory (i.e. even they don’t use Application Support).
I guess I am happy with how fish and git and others do it, and wish other tools would follow suit for consistency.
Isn’t setting the XDG environment variables a pretty good sign that you want to use XDG?
Not really - overloading “the location to use if you’re using XDG” to mean “you should use XDG” has a bunch of edge cases that can cause havoc.
I don’t understand the point of shoveling a few dozen files from $HOME to some other directories. Now, in stead of just opening $HOME/.some_file, you open $WHAT_EVER_DIR_THAT_SATISFY_YOU/.some_file. Do we really gain anything here? If all you want is automatic setup or sync your configs, you can just list all these files you want to sync up and put it in a single file. Any synchronization/backup utility would be happy to do the rest.
What’s better with everything referring $HOME? If you want to test your new environment, just
mkdir "$HOME/new_home" && HOME="$HOME/new_home" launch_process_group_with_new_HOME
The point is that I want to backup my config files, but I don’t want to backup caches. With XDG, there’s .config and .cache. I can backup the first, done. Without? I have to look at each dotdir, and see which parts are config, and which are cache.
Furthermore, I may want to put caches on an ssd, but configs on hdd. Or even make configs readonly.
Or put my $HOME on tmpfs, and symlink configs in. Symlinking .config is waaaay easier than symlinking a zillion files spread across a dozen dirs.
Ugh under my ~/.emacs.d there’s eln-cache, recentf, auto-save-list, saveplace and even .cache (who puts dotted dirs inside already-dotted dirs??).
Apparantly you can put the init file in ~/.config/emacs now, but I’m guessing a bunch of packages still put cache-stuff in the same dir as config-stuff
Yeah, there are a couple of things that need a bit of tweaking to behave correctly. Luckily, for Emacs, you can put all those cache-y stuff elsewhere with a few lines of configuration.
But then come all the Electron apps, and that’s just sadness. Still better than littering ~ directly, though, because writing a list of files/dirs to exclude is easier than writing a list of what to include.
Yeah, we gain not having 200 random garbage directories inside our homes. It’s my home, please let me arrange it however I want.
To be fair, having random boxes stuffed everywhere kinda describes my physical home right now..
I wonder if there’s a correlation between how much people care about XDG directories and the state of their physical homes.
I care a lot about my $HOME. I went to great lengths to keep it neat and tidy, to the point of having it on tmpfs.
Now, my work room… oh boy. Just the other day I found a box we didn’t open since we moved in ~4 years ago! That was a blast, it had a lot of baby clothes tied together with USB cables.
I don’t give a fig about XDG and will get around to the boxes soonish (recently moved!)
I backup $XDG_CONFIG_HOME, ~/.config, because it for-sure contains configuration files. My home directory contains all kinds of crap. In your case, and the current situation, I can’t just backup ~/.config. I have to back that up, plus 20+ hardcoded directories dumped in $HOME; and for every application I install, I have to run it, check if it stores data in ~/.config or $HOME, and if it’s in the latter I have to manually update my backup script to add the new application’s dotfiles.
One of the nice properties of the XDG dot file spec is that if your preference is for everything in $HOME, you can express that, and then everyone is happy.
My .config is a git repo, so when I set up a new machine / VM, I can just clone it and everything works as I expect. Making your home directory a git repo adds a lot of complications (lots of things with git integration walk up the tree until they find a .git file and they get very confused if there’s one containing the entire home directory).
Because it’s not idiomatic for macOS, iOS, nor Windows I’m sure.
Having well defined locations helps the OS manage data. Stuff in ~/Library/Caches can be deleted to free up disk space, and backup tasks know to ignore it. Prefs and other app-specific files named according to the app’s bundle ID can be deleted if the user deletes the app (the OS doesn’t do this, but some utilities like Hazel do.) Et cetera.
So what’s “legacy” and what’s not?
I guess ~/.ssh/ can stay, and ~/.bash_profile, and ~/.zshrc, and ~/.emacs, and ~/.vimrc, and ~/.gitconfig, … meanwhile my ~/.config/ has nothing of value. So if I had to pick one, I’d pick ~/
I guess I’m the outlier? I’m on a Mac, if you couldn’t guess.
You can store git config files in ~/.config/git/config, as I learned when I switched my got configuration into Nix home-manager and saw that it used that as the file path. I no longer have a ~/.gitconfig .
The same is true for my neovim and fish shell config files, they can also go in .config subdirs. So I actually don’t personally have any of the config files you mention directly in my homedir except for .ssh .
For Zsh, you can define the ZDOTDIR env var, and point it somewhere where your .zshrc &co files are located
For Zsh, you can define the ZDOTDIR
For Zsh, you can define the ZDOTDIR
But where do you define it? In ~/.zshenv ? That still leaves you with a file in your home directory.
This is a generic problem for shells. All of the XDG directories can be specified in environment variables, but typically the shell is the thing that runs first after login and sets environment variables.
But where do you define it?
But where do you define it?
You can make a wrapper script called zsh that sets the env var and launches zsh, that’s what I do (quite easy to to do with Nix)
It should also be possible to set them at system level in /etc/environment iirc ¯\_(ツ)_/¯
You can define it with PAM, via /etc/environment or similar, and then you don’t need ~/.zshenv.
Which of those work for users that aren’t root on the system?
PAM, though it is getting removed: https://man7.org/linux/man-pages/man8/pam_env.8.html
For anything that is assumed to be started through systemd, (gnome, kde, sway, et al), https://www.freedesktop.org/software/systemd/man/environment.d.html
For things started as part of an X session, ~/.xprofile, ~/.xinitrc, or ~/.xsession, alas, not following new conventions, but whatever
The great thing about XDG is that you can pick ~/, while I can pick ~/.config and ~/.cache and the rest, and we can be both happy. Unfortunately, there are a lot of software which doesn’t let us pick, so one of us will be sad from time to time, which is why the OP raised the issue in the first place.
No recommendation for Windows… 🤔
Most of the Windows configs (for modern apps at least) seem to live in %APPDATA%
There’s the whole registry vs. INI vs. normal config files thing. And the registry itself is “logitudinally divided” …
Yep, I noticed that. The situation is horrible on Windows, honestly. Some things put everything in Documents as if it is of equal importance to your PhD thesis, some stuff goes in %APPDATA% and it just hides there, some programs put images under Pictures so you can view your Valorant headshots alongside photos of your toddler inadvertently.
I mean, it’s a lot like most software these days: it doesn’t even believe it has a lane it should try to pretend to stay in.
Recommendation is to use WSL
Thanks! I had no idea there were specific per-task directories for Unix systems.
Whenever I see one-off manifesto sites like this one, I always wonder if this is really the best way to get the word out about these things so that we can affect real change. I agree wholeheartedly with what the author has laid forth here, and I think it’s a good thing for us to push towards, but how are people meant to keep track of these various sites and use them to make something happen? How are people meant to discover them, outside of posts on forums like this one? I have to imagine that the type of person that’s making decisions like these probably aren’t the type of people that are reading a website like this.
Within the past week, we’ve had two highly rated posts come through that match this same format:
There are a few more that I can think of off the top of my head:
And many more that I’ve seen but can’t recall at the moment (which is part of the problem!). I don’t have a solution to this, and I do think these sites are effective at getting their point across, but that requires someone to find the site in the first place - which probably also requires realizing that there is a problem to be solved.
I don’t think the main goal of these sites is to be discoverable by people who are unaware of the problem but for those who are aware of the problem to share.
The general idea is the same that I often write blog posts about common arguments I make. This way I can just like to the blog post (usually with a bit of context and relation) which is (theoretically) better written and fully thought out rather than re-iterating the argument again and again off the top of my head.
The own domain is likely for a) fun b) it seems more professional and maybe a bit of c) better SEO so that others who have the same opinion can find the page more easily.
Here’s another one for the list: https://no-color.org/
Well, this is a link aggregation site. Every highly rated submission (even the ones that generate a lot of controversy, like the stale bot one) is read by a lot of people, who presumably take some action based on it.
Sites like this and HN remain quite influential in some circles (btw the HN submission for the stale bot story barely registered). If you want to effect change, getting your single-issue web page on a site like this is a good first step.
Semi-related: for a while now I’ve wondered if we should have a grass-roots standard for documenting what the files are for in sufficient detail that an average user of the software could fairly easily decide whether they’d want to do common things like delete, back up, or sync the file between systems without having to go read source or whatnot.
Nim has a library for this: https://git.sr.ht/~ehmry/freedesktop_org
This stuff is trivial to implement, not having a library is not an excuse for not honoring XDG_CONFIG_HOME.