Somebody should tell that to the Rust people. They have a .cargo and a .rustup folder in ~, plus an extra heavy target folder for every project. Would be much nicer if they put the cache one .cache
Sure, hidden folders are a mistake, but less of a mistake than not adhering to standardized folder structures and just littering in people's home folders.
Oy. That surprised me. I am quite familiar with the notion of common keyboard shortcut that I can't get on my Norwegian keyboard. Command-(left/right) square bracket is very common, but at least that is usually associated with a menu item so I can assign a different shortcut. But now I learned that on a French keyboard, period is shift-semicolon!? Which makes me wonder: Do the French use the semicolon more often than the period? Oh well, once in a while it sucks not to be American. ;-)
While I've not fully dug into all of those links, that is rarely the case and it makes the conversations harder when people over simplify situations like this. Generally, I've found when people make assumptions like this, the underlying requirements are a lot more involved and its not a high enough priority for the small group of overtaxed individuals.
In my experience, the usual reason for a project not using the XDG Base Dir spec is because somebody on the project simply doesn't like it, particularly XDG_CONFIG_HOME defaulting to $HOME/.config. Resistance to the XDG Base Dir spec really does seem to be rooted in personal preference, I've never seen an objection to it on any technical basis.
The best arguments against it that I've seen are "many other projects don't use this spec, so why should we?" (e.g. our project should be the last to adopt it.. but why?) and arguments along the lines of "XDG_BIN_HOME isn't in the spec, therefore we shouldn't use XDG_CONFIG_HOME", which just seems like a lame excuse.
XDG_BIN_HOME is crucial, without it, not supporting the spec seems like the right call. Better to deal with the status quo until updates happen than to get stuck in bikeshed hell.
You're letting perfect be the enemy of good. Other projects, like python, use $HOME/.local/bin as the spec suggests and it works out fine in virtually all cases.
> "User-specific executable files may be stored in $HOME/.local/bin. Distributions should ensure this directory shows up in the UNIX $PATH environment variable, at an appropriate place."
> "Since $HOME might be shared between systems of different achitectures, installing compiled binaries to $HOME/.local/bin could cause problems when used on systems of differing architectures. This is often not a problem, but the fact that $HOME becomes partially achitecture-specific if compiled binaries are placed in it should be kept in mind."
The omission of XDG_BIN_HOME is regrettable, but not a showstopping problem unless you want it to be a problem. W.r.t. a single $HOME across multiple architectures, "not often" a problem is an overstatement of the problem; the number of people using a single $HOME across multiple architectures is a rounding error (I say that as somebody who once did so) and such people are already accustomed to dealing with the difficulties that arise from it. They're going to hoist themselves with Go and Rust's defaults anyway.
You can also use the environment file linked in that blog post to tell Rust to follow the XDG standard. Not perfect because it is not the default behaviour but it is doable.
At least for rust applications of your own, you can use the library https://github.com/dirs-dev/directories-rs to follow XDG on Linux as well as platform conventions on Mac and Windows.
It's important on any system, not just XDG. The OS will assume you do, and offer features based on it, such as cleaning cache dirs, emptying temp dirs, etc.
It's not just about being tidy, although it's important.
But remembering all that stuff is annoying.
If you use Python, the wonderful "appdirs" package will make using the best dir for the job on Windows, Mac and Linux, easy and transparent: https://pypi.org/project/appdirs/
I wish it was part of the stdlib.
Another thing that grind my gears is people putting files inside their code project folder for development.
It should be something configurable, that by default use the OS dir for prod, and "../var" dir with everything on it in dev.
Less gitignore trouble, let's watcher overhead, less indexing for nothing, less clutter in file explorers, less possibility for errors.
But you need to provide an easy way to locate those files, such as a cmd line entrypoints, otherwise it's painful.
One of the things that changed my life recently, that I hadn't seen before: NeoVim has a NVIM_APPNAME variable that lets you change the app name.
So when I wanted to try AstroVim, I just set NVIM_APPNAME=astrovim, and dropped the files in ~/.config/astrovim instead of blowing up my existing (shitty) ~/.config/nvim.
I really wish the idea of configurable appnames was a part of the spec! (or a well-known extension!)
I actually have something similar in some of my old old projects. And I'd expect I ripped the idea off from somewhere. But I don't know who to cite. :(
Historically a lot of programs would use argv[0] as their name. Vi-family editors do have an excuse not to do that, since vi uses its name for other purposes, e.g. `view` for readonly.
I want to share my nvim config between both my home Linux machine and my Mac at work, but I don’t want to share my config for gnome and its apps. So now I’ve got to maintain a script to go one more subdirectory deep to pick which dotfiles to sync and which to ignore...
> Easier to temporarily ignore the config
> It is easiest to set XDG_CONFIG_HOME=/tmp/dir
This is such an unreliable way to do it, even within the xdg world. What about stuff in ~/.local/share? It’s a lot easier and more reliable to just set HOME=$(mktemp -d)
Personally when I’m trying to start from a clean profile, I find it much easier to just go and blow away ~/.mozilla than to go and surgically remove .config/epiphany, .local/share/epiphany, .cache/epiphany, and whatever gconf (or gsettings or whatever windows registry clone we’ve got now) settings it’s got.
i want to mess up with wine, now I just backup ~/.wine, do whatever, restore.
With split folders, i'd have to backup a bunch of folders (.config/wine, .local/share/wine, .local/lib/wine or wherever the files, registry, dosdevices and other stuff would be put).
> i want to mess up with wine, now I just backup ~/.wine, do whatever, restore.
You can set WINEPREFIX to use a non-default prefix path (other than `~/.wine`).
Note that the prefix doesn't contain everything that wine spills all over your home.
It adds (XDG `.desktop`) launchers & menu/desktop shortcuts, file type associations, icons, etc. to the usual locations.
Usually I need to upgrade something within a wine environment, and sometimes the new version of whatever software doesn't work, so "cp -r .wine .wine-bak", do whatever, fail, rm, cp back, and it's done.
Then you have a whitelist which is clearly not that hard to maintain
For the cache, the opposite argument is just as true:
If I want to clear cache from everything to save space, I can just `rm -rf ~/.cache` instead. And this case is a lot more common than wanting to "start from a clean profile" :/
But can you? Did you really close all the apps using ~/.cache? What if some app is just doing some cleanup operation, moves a bunch of stuff to cache, and the files are missing now? Did you just delete android studio cache in the middle of a compile?
You can also make a script like your .config, but it's called "clear_cache.sh", where you hardcore a few paths you usually clean manually.
Programs that cannot deal with removing ~/.cache at any point are simply faulty because at that point it is state and not cache which by definition can be recreated at the point of access.
That was a bit exaggerated I never clean fully the cache, mostly just specific apps but as long as I have everything closed (GUI and CLI apps), I don't really care what background services are doing and if they get upset because of this. I'm not on a server, that's my laptop so there is no critical stuff going on and once the app I use are closed that's good enough
How did OP manage to get rid of ~/.mozilla? It's the only offending dotfile left in my $HOME and the stickiest. Until Mozilla fixes their 19-year-old feature request to support XDG [1], I couldn't find a workaround that wasn't a total hack.
XDG sucks for the only reason that it is really difficult to configure user directories to one's taste.
For instance, to get rid of Download, Templates, Desktop, Public Share, Documents, Music, Pictures, Videos directories I not only have to point them to somewhere else, I also have to make sure Desktop and Download do not point to the same directory, otherwise my config will not be used.
Here, after literally hours of researching, I figured the config that works:
Yeah, we have a straightforward and widely established standard. Just put the related files in .programname .
Now let's bikeshed and scatter them randomly across several places. To make it more fun let's make those locations programmable with environment variables so you won't even know where to start looking for a particular related file. Add lots of categories to create ambiguity. Make some of the default locations single level and others multiple level directories for no apparent reason for extra fun.
That has never been a standard as many programs have multiple dotfiles in ~. But even if it was, there are still good arguments for the XDG Basedir Spec: common way to change the location via environement variables as well as ability to split cache and non-cache.
Having this depend on env vars is an anti-feature in my mind. It's much harder to ensure env vars are set to the "right" values in all situations then it is to just use some well-known paths.
Come on, you just use a fallback if it's unset, you can even use your "well-known" paths for that if you want to. Don't pretend this harder than it actually is! This is like lesson 1 to using environmental variables, it's like saying you never free your mallocs because it's "much harder" that way! The OP site even provides code examples for popular languages, how can you imply that randomly littering your user's $HOME directory is the viable alternative here?
> Now let's bikeshed and scatter them randomly across several places
"Now"? The initial draft of the XDG Base Directory Specification was published in 2002.
I don't my backups to include gigabytes of worthless cache files. I want them isolated somewhere, anywhere, so they can be easily excluded in my backup scripts.
I completely agree with the article that more people should use the spec. I already do this for all my personal projects and nothing drives me up the wall more than seeing random config files strewn about.
It also provides an easy target for freeing disk space if you do run into issues (just `rm -r $XDG_CACHE_HOME`).
That said, I do think the spec would be improved by defining what constitutes a "user-specific data file" and how that is different from a "user-specific state file". Wouldn't "user-specific data files" just be "files" from a users perspective? I like the idea they have for this, but it's kind of under defined.
Though that's probably a good thing because no one wants a ontological tome to wade through when working on a bash script or the like.
In what world is simply dumping config items for your app in the user's home directory sensible? Why stop at config items? Do cache or temp crap too. The thought process of persisting with this baffles me. Microsoft would be absolutely ridiculed if one day your msword preferences appeared on your desktop as an XML file, and no matter what, it kept reappearing.
Yeah, although, I'm not a huge fan of Microsoft's default config file locations either.
Some examples:
- PowerShell Core's default profile is in $HOME\Documents\PowerShell -- or if you have OneDrive enabled, $HOME\OneDrive\Documents\PowerShell.
- Windows Terminal is $HOME\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json.
I can feel pretty confident assuming that if Microsoft can place their power users' config files for Microsoft's Terminal and Microsoft's primary shell in seemingly unrelated locations and not get huge complaints, I would imagine that most Windows users are probably not people who would ridicule Microsoft for placing an XML file in their home directory.
EDIT: I used these examples specifically, because a Terminal Emulator and shell profile are the exact kind of apps you would store configs for in a dotfiles repo.
Microsoft (and subsidiaries, e.g. 343 Industries), is somehow even worse at adhering to its own norms. Now, I have .vscode and .dotnet folders in the top level of %USERPROFILE%. Even Visual Studio creates a stupid %USERPROFILE%\source\repos directory tree, when I never told it to.
I am fed up by this, and have completely given up on maintaining the tidiness of my %USERPROFILE% and %USERPROFILE\Documents. Almost all video games have absolutely no respect whatsoever for OS norms, and just spew their config and save data all over the damn place in %USERPROFILE%\<game title>, %USERPROFILE%\My Games\<game title>, %USERPROFILE%\<developer or publisher>\<game title>. The worst thing is that Windows has a place specifically for video game saves: %USERPROFILE%\Saved Games, or programmatically in C/C++: `SHGetKnownFolderPath(FOLDERID_SavedGames, ...)`.
To add to the mix, I also have GNU/Linux-first programs like SSH, Gradle, etc that just straight-up create dot-directories and dotfiles in the top level of %USERPROFILE%. Windows is not Unix/Linux; a dot prefix does not mean 'hidden'. Windows has an explicit 'hidden' filesystem metadata tag that programmers need to (and frequently forget to) set: `SetFileAttributesA(filePath, FILE_ATTRIBUTE_HIDDEN)`.
The second example is a nice start, but I'd really like to see invisible files/folders in ~/ done away with altogether.
So starting with that example, I might add a visible ~/Library/ folder, then move ~/.config/ and ~/.local/ in there as ~/Library/Config/ and ~/Library/Local/ as normal visible folders. Same for .bashrc, .profile, etc; put them in ~/Library/Config/ without the dots.
If everything honored this spec, including the part where it reads environment variables to see where the different directories are, you could do that by sticking the right variables in your environment.
I think the one legitimate exception to the rule is profile, because you need that in order to set the variables in the first place. So that one would somehow have to be hard coded to at least have a wider search path
Huh. So I was about to disagree because that felt like a kludge, but actually you're right; setting your shell and its environment are both things that have to be set before the user's normal environment is working for bootstrapping reasons, so yeah, it does make perfect sense to cover both with the same mechanism. Or maybe to make it more generic we could replace the "shell" line in passwd with a "login command" entry, which is always executed by the system /bin/sh with the system environment from /etc/profile? Then you could set it to `XDG_CONFIG_HOME=$HOME/mydotfiles /bin/shell`, or `/bin/decrypt-my-home; export XDG_CONFIG_HOME=$HOME/Library/config; exec /bin/bash --init-file $HOME/Library/bash/bashrc` or whatever you want.
So perhaps you can set the value of ZDOTDIR in one of the systemwide locations to use "$HOME/foo/bar/zsh/" and this way zsh will use ~/foo/bar/zsh/ as the location for the user specific .zshrc and other mentioned files for every user
So that's not any fault of XDG, that's you forcing applications to use it when they apparently don't support it natively. That's either 15 or 19 lines of application bugs.
No, you said "when your xdg list gets huge, apps should just use xdg out of the box". But the link you shared shows only 4 lines in your xdg list. 4 lines is hardly huge.
Why should I have to maintain a list of applications that don't conform to the standard? I tried to, and the list keeps growing. I'm done screwing around with it, I don't care how cluttered my homedir gets anymore.
Luckily if you’re a developer on MacOS, you can have that too! In addition to ~/.config and a million .dotfiles and .dotdirectories from decades of unixy tools! Truly a cornucopia.
Sure. In software of mine distributed by Debian, there's usually a "debian/patches" directory, that I didn't add, that's changes the Debian project wanted to make to the system. I'm sure there's a formal name for that system. Most Debian packages seem to have one.
In Windows we get dotfiles from any tool badly ported from unixland, plus the myriad ways specified by various Windows standards over the past several decades, plus the innumerable ways that different entities have chosen to interpret those standards, plus whatever bullshit non-standard locations some asshole thought up and decided to ship.
Where is the config for program X?
It could be in the same directory as X, HKLM\Software\X, HKCU\Software\X, The HKLM\Software\XWOW6432Node\X, AppData\Local\X, AppData\Remote\X, AppData\LocalLow\X, ProgramData\X, USERPROFILE\.X, USERPROFILE\Documents\X, USERPROFILE\Saved Games\X, USERPROFILE\Documents\My Saved Games\X, USERPROFILE\.config\X...
Yep. Makes backing up configurations on Windows systems somewhat nightmarish… it's most practical to just back up the whole install and then pray that you'll never have to go digging for any specific bit of config in particular.
> The second example is a nice start, but I'd really like to see invisible files/folders in ~/ done away with altogether.
A great many amazing tools shall, by default, skip searching in hidden files (and gain a great speedup thanks to doing that). You'd have to modify all these tools so that they'd skip Library/ by default.
Also, related to that, what would you do with .git/? Move prjs/fizzbuz/.git to Library/fizzbuzz/git while keeping prjs/fizzbuzz?
Things like .git are fine I think, because they’re localized one-offs and have more of a reason to be hidden. It’s the home folder’s function of a junk drawer that makes invisible files/folders a problem there.
Yeah, it's a bit alien on macOS. There is no good mapping for some of these folders.
For example, on macOS application configuration isn't even supposed to be done directly via application-specific files. macOS has its User Defaults subsystem, with `defaults read`/`defaults write` commands. And of course this isn't usable by typical command-line tools that don't have a Bundle ID.
The system that you mentioned is specifically for macOS Desktop apps. I think even Apple is drawing a line there. I don‘t know of any Apple commandline tool which has a configuration in plist format etc. But I might be wrong.
Apple ships some BSD and Linux tools (openssh, git) without changing how they store configuration, but anything written with macOS in mind has other methods. For example, Apple's command-line build tools for Xcode inherit GUI Xcode's settings and project files that are plists. launchctl uses XML plists in ~/Library instead of /etc. Daemons like Spotlight and Time Machine are configured via plist-editing GUIs or mdutil/tmutil commands.
Oh huh, I was always under the impression that "X" meant "Cross", as in "Cross-Desktop Group", since they were working on standardizing things across different desktop environments. But I guess the "X" was just a reference to X11? I guess today it encompasses a lot more than X11-based stuff, though...
I see some comments about users having a hard time cleaning their home directory and advices to use tools (boxxy?).
But I read this post as an advice for developers not for users. A long crusade for standardisation may I say ;-)
Any GUI file manager worth its salt can hide invisible and/or dotfiles, it’s table stakes — and just a GUI representation of that same terminal output.
> ... State :... if the data is unique for a given machine, the file belongs [to $XDG_STATE_HOME / $HOME/.local/state]
This statement is misleading/wrong. Like all other XDG stuff, it's not about the machine, it's about the particular user.
Also, why does the author consider the given positive example clean and tidy, when it has files .profile and .bashrc placed directly in the user's home directory? Following the rules, these files should be within the .config/ directory as well.
> This statement is misleading/wrong. Like all other XDG stuff, it's not about the machine, it's about the particular user.
No, it's both. The XDG state dir is for things that are also machine-specific so that, e.g., it doesn't make sense to sync them as part of your dotfiles.
> why does the author consider the given positive example clean and tidy, when it has files .profile and .bashrc placed directly in the user's home directory? Following the rules, these files should be within the .config/ directory as well.
They should! Some shells have kindly moved to follow this convention following requests from users who like it for other apps and would prefer more uniformity w/r/t config file location conventions, e.g.: https://github.com/elves/elvish/issues/383
> No, it's both. The XDG state dir is for things that are also machine-specific so that, e.g., it doesn't make sense to sync them as part of your dotfiles.
It was probably written back when it was more common to have your home on NFS, although I'm not sure how that would work without needing to use overlayfs per-machine or something.
> This statement is misleading/wrong. Like all other XDG stuff, it's not about the machine, it's about the particular user.
No, it's correct. "State" data is machine-specific. You might run an application that needs to generate a machine-specific identifier on first run and save it somewhere. For someone who shares their ~/.config among multiple machines, that shouldn't be synced.
> when it has files .profile and .bashrc placed directly in the user's home directory?
There's no other good option, as you may have a chicken-and-egg problem: often people put their definition of XDG_CONFIG_HOME in their .profile or .bashrc. Bash can't know where to find the file if the file tells you where to find it.
Sure, it could just hard-code ~/.config (and that would be correct for most people), but for people who have it set to something else, now they just have an unwanted ~/.config directory. Might as well just stick it in ~/ and live with it.
Of course there are alternatives: someone could set those variables via a PAM module or some other mechanism that might be able to set it before the shell even starts, but I'm not sure we should expect that to be common either. You could also use /etc/profile or /etc/bashrc, but then you have to either set it for all users, or have an if/case statement or user-mapping file that sets things according to each user's preference. If this is a shared machine where most users don't have root access, then you need a mechanism that lets users update their preference.
Yes, I get that those things are not the common case: most people have a single-user desktop/laptop where they have root access. But we need to consider the edge cases too.
> Also, why does the author consider the given positive example clean and tidy, when it has files .profile and .bashrc placed directly in the user's home directory? Following the rules, these files should be within the .config/ directory as well.
I was wondering about that part as well. Then again, I also have high standards for non-hidden stuff as well, and only have ~/Downloads from the ones they list. I do have a ~/Dropbox/home` with `docs` and `images` (as well as "video", but not synced locally), as well as ~/code and ~/dotfiles. If anything, having non-hidden clutter stresses me far more than hidden clutter; I have ~/.scratch for random on-off things I need, and I'll often utilize my disdain for extra stuff in the home directory as a way to make sure that I don't procrastinate something too long (e.g. if I need to make a phone call for some errand or something, I might put `phone.txt` in my home directory with the number I need to call, and seeing that every time I look at my home directory I get a reminder until I do it and delete the file).
It doesn't feel tidy to have .cache or .config out at the root of home folder either. IMO, those should be pushed down into .local. At least with the xdg base spec you can do that!
That's the thing I always thought was weird: why isn't the default value for XDG_CONFIG_HOME ~/.local/etc, and XDG_CACHE_HOME ~/.local/var/cache? I guess they wanted to make it easier to find for people who wouldn't be familiar with the spec (i.e., most regular users).
Even with .config and .cache, the number of .folders in homedir stays constant vs the number of apps installed, which is the most important thing IMO. From there it could be argued that if you allow .local to exist at all and it only contains always the same three subfolders, you might as well move those up and benefit from shorter, more meaningful paths.
Not completely true. You can launch bash with the --init-file flag and put the bashrc file wherever you'd like. Could even change /bin/bash or whatever your default shell is to be a script that launches bash with that flag provided.
I strongly disagree: the dot files cause very little inconvenience because they’re typically hidden and they’re easier to type and list than the XDG spec stuff
The XDG defaults put them all (per category like config/data/cache) inside one 'typically hidden' directory, how is that not better?
You're also making an assumption that the alternative is $HOME/.appconfig, which it might be, but that's not any particular standard. It might just as well end up $HOME/app.config or $HOME/Library/Application Support/MacOs/Resources/App.app/config/Config/Resources/config.
The kinds of programs that were putting in entirely nonstandard paths (~/app.config), or paths specific to macOS or Windows, are still doing that.
But when it comes to a 'well-behaved' Unix program, there used to be one place to look for its configuration, and now there are three.
That is, a program foo could still have its configuration in ~/.foo, but now it can also have it in ~/.config/foo or ~/.local/share/foo. If I don't know where the configuration is already, I have to check all of them.
I know ~/.local/share is supposed to be for "data files" and ~/.config is supposed to be for "configuration files", but in practice the distinction seems to be rather unclear.
Also, ~/.local/share/foo is a lot slower to type than ~/.foo even with tab completion. Why does that path need to be two directories deep? ~/.config/foo is less bad but still slower.
With the XDG Basedir Spec you don't have to use ~/.local/share and ~/.config if you don't like them, they are just the defaults after all and you can set the respective environment variables to whatever you want. That is not an option you had before.
Admittedly, it would have been nice if the variables were defined in a way that let you reproduce the traditional dotfiles, e.g. by pasting $XDG_DATA_HOME in front of the app name so you could set XDG_DATA_HOME=$HOME/. and requiring an explicit trailing slash if you want them to be a directory.
Sounds like your issue's more with change than specifically what the spec says then. I get that, but also.. where would we be? (But then, I use a rolling release distro (btw) and happen to like systemd.)
> Why does that path need to be two directories deep?
It doesn't, set `$XDG_DATA_HOME` to something that isn't.
Eh, for me it's that it's a grouping I don't like. I would really rather have the config and data bundled together. It's kind of like OOP where the functions and data are bundled together.
> The XDG defaults put them all (per category like config/data/cache) inside one 'typically hidden' directory, how is that not better?
Because it puts them in an overengineered, overly cumbersome hierarchy under that. It reminds me of OSI.
> You're also making an assumption that the alternative is $HOME/.appconfig, which it might be, but that's not any particular standard. It might just as well end up $HOME/app.config or $HOME/Library/Application Support/MacOs/Resources/App.app/config/Config/Resources/config.
Either of the first two is easier to work with than the XDG-compliant way, and the last is no harder.
FYI, and nothing personal, but your comment is more or less coming across to me as "whelp, the inflexible delegation has spoken".
I go to great lengths to maintain a flexible mindset, to try to get the best out of a new approach. Hearing/reading someone trying to throw a shallow take-down of something they haven't tried doesn't read as "ooh that person is so cool I'm super convinced"... it comes across more like "oh, poor fella went and got his brain rigidized... and at such a young age".
But maybe you'll come around. Maybe people will come around and realize the ankle-deep hot takes are worse than useless and we can all get back to the good stuff.
On the other hand, I do have my own suspicions. At first glance it does simply sound like another layer of idiosyncrasy to jam into the memory hole, something that will certainly never be universally adopted and just add more hidey-holes to search for config files.
But, as I hope I made clear, I'm willing to give it a shot because I don't trust myself to have absolute insight into a thing after a couple minutes reading. There may well be aspects to this that I can't conjure, but will really like after all is said and done.
> Hearing/reading someone trying to throw a shallow take-down of something they haven't tried
I mean, I've lived with XDG messing up where my config files are for several years at this point. How much "trying it" do I have to do to be allowed to have an opinion?
> Why don't you set your XDG vars to where you want to put them then?
I hear that argument often. When a program uses $XDG_CONFIG_HOME/tool/ for its config files, to what value should I set XDG_CONFIG_HOME to get the old behavior where it puts its config in $HOME/.tool/?
That's an interesting question, and I don't know the answer. A Google search and ChatGPT request provide no answers, so this seems like an uncommon request. It seems like there ought to be a way to achieve this reasonable request though.
Possibly setting it to $HOME would make all/most programs assume that you wanted it to live in $HOME/.tool rather than $HOME/tool, but I'm guessing. I don't know if that's the standard.
I'm not sure it is so uncommon - just that there is no answer. I'm pretty convinced that a lot less people would complain about the XDG Base Directory Specification if that would be possible.
I'm one of those (though I usually do not publicly complain about it).
> an overengineered, overly cumbersome hierarchy under that.
You put config files in
$XDG_CONFIG_HOME/app/whatever with a fallback to $HOME/.config/app/whatever, and data files in $XDG_DATA_HOME/app/whatever with a fallback to $HOME/.local/share/app/whatever - what exactly is over engineered or cumbersome about that?
The hidden part is another usability mistake, but the main benefit of XDG is respecting user's choice who can set an env var to avoid the mess, hope you wouldn't disagree with an option the improves someone's life without affecting yours in any way?
Why would you hide the files a user is explicitly expected to tweak to configure an app's behavior and call it an improvement??? It degrades the config experience, what part of "usability" is improved?
A couple of years ago I wanted to use xdg dirs in a Python app I was writing. There are seemingly two packages for this, neither of which I could get to work.
Overall I don't think xdg dirs on Linux are really as amazing as some people think. For example it is said that one can just back up the config dir to carry all the configuration over to the next install, but apps often dump the default configuration into the config dir, which you don't want to carry to the next install (which will have different versions, so probably a different default config) because that might break stuff. In the end you have to carefully look over all the configuration to see what's worthwhile to take with you, and it doesn't really matter if that's in ~/.appname or ~/.config/appname
> For example it is said that one can just back up the config dir to carry all the configuration over to the next install, but apps often dump the default configuration into the config dir, which you don't want to carry to the next install (which will have different versions, so probably a different default config) because that might break stuff. In the end you have to carefully look over all the configuration to see what's worthwhile to take with you, and it doesn't really matter if that's in ~/.appname or ~/.config/appname
Depends really what you want. If you want to have a fresh system with some of your config then sure, you need to decide what you want. If you just want to keep the same setup then ... I have been using the same $HOME for over 15 years (same for the rest of the system too). Some big upgrades (e.g. KDE3->4) required some manual intervention but most programs handle old config well enough in my experience.
> There are seemingly two packages for this, neither of which I could get to work.
I am really confused as to how that happened so I will show examples of all the three options I know of and how to use them to get a path of a config to load:
from appdirs import user_config_dir
import os
# Company is optional for windows support to work the way windows users expect it.
# You can also specify version to version the dirs.
conf_dir = user_config_dir("program", "company")
conf_path = os.path.join(conf_dir, "config.toml")
https://pypi.org/project/xdg-base-dirs/ - just bare bones XDG support with fall backs and pathlib support, no special windows support, but will still work for user configs
https://pypi.org/project/pyxdg/ - from freedesktop, includes more than just the base directory specification - a bit of a weird interface but technically can support more complex situations
from xdg.BaseDirectory import load_first_config
import os
conf_dir = load_first_config("program")
# conf_dir will be none if there is no "program" dir/file in any of the paths XDG_CONFIG_HOME or XDG_CONFIG_DIRS
if conf_dir:
conf_path = os.path.join(conf_dir, "config.toml")
Yes there are 3 options (but what modern language doesn't have this problem for everything?) and you have to pick one. It's not that hard to evaluate these, the only caveats you have to consider are: do I care about system-wide configurations and properly handling overlapping configurations, or do I just want a user local config directory. I have written the above code with consideration for the latter. If you are allergic to unnecessary dependencies (and I am so I can sympathize) then for the simple use case I outlined (with the same level of cross-platform support as xdg-base-dirs and pyxdg) you can just use this code:
from pathlib import Path
import os
conf_home = os.environ.get('XDG_CONFIG_HOME')
conf_home = Path(conf_home) if conf_home else Path.home() / ".config"
conf_path = conf_home / "program" / "config.toml"
I hereby release all code (within this comment) under CC0 (I doubt you could even claim copyright on something so simple anyway, but let's avoid issues in advance).
> but apps often dump the default configuration into the config dir
This is not an XDG dir related problem, and not even that common of a problem. You are right that it IS a problem (and applications should be encouraged to avoid this, just as they should be encouraged to avoid littering the homedir) but strictly speaking, using .config while littering it with auto-generated configs is better than not using config while doing the same. It really does make life easier when configuration is generally kept separate from other types of data by following the XDG base directory specification.
Oh yeah, I used to do that and diligently configured vim and others apps to use $XDG_{DATA_HOME,CONFIG_HOME}. Lots of razor cuts and more maintenance annoyances, not worth the time. I reverted to using the defaults on each new machine I configure these days.
Oh I‘m fighting the battle for a clean home directory for years. I even use a setup on macOS to set specific environment variables via systemd during login so I can link them into the .config directory.
Only issue with my setup in general is that I can‘t just replicate it for other people. I moved .aws directory in .config/aws and I sometimes forget what the default for most tools is or where I helped the tool out to „find the right path“.
I also make sure when writing scripts/cli tools to use the XDG spec. In rust I use the dirs crate for example. I even go so far to never hardcode it for my own config scripts/files just in case I think about going from ~/.config to ~/.my_configurations or whatever.
I have a very dumb question: why does the article use `find` with `printf` and depth specification, as opposed to the simpler `ls -a`? I'm assuming it has something to do with portability, but `ls -a` is already in POSIX. I'm a bit confused.
Hmm. I think it's because `ls -a` will not visually differentiate between files and folders and will also show `.`and `..`. and will span contents over columns while find will return a line by found items.
Lazarus (https://www.lazarus-ide.org/) has built-in support for the configuration folder ($XDG_CONFIG_HOME) in the user context and in the global context:
A small note I do not have seen so far in comments here: the article told about "easier backup", actually I strongly disagree. I do keep some configs I've write myself/edited myself. Most of the rest are automatically made stuff useless to be backed up and sometimes also inopportune to restore since a version to another some (cr)applications do badly digest their own automatic config.
My one gripe is that many systems do not provide a writable XDG_RUNTIME_DIR in all cases because the requirements in the specification are impossible to meet at the same time (the specification does not acknowledge the existence of “su --login”). This means that applications still need fallback code, which historically has been buggy (e.g., using shared /tmp without safeguards).
I have been a staunch supporter of XDG basedir standard for many years. Unfortunately it has become clear to me that it is simply not enough. So instead I have started to abandon home as the place to store my files. I use a subdirectory in home instead, the name of which is purposefully non-specific.
Exactly! Fixing /home/<user> is a lost cause. You can't get thousands of applications to follow a common sense standard. It's more pragmatic to not store the files you care about in the dumping ground that's /home/ .
Beware that any directory other than one under /home might not enjoy the same protections by default by other programs, like systemd’s ProtectHome setting. You’ll also probably want to adjust some settings, like AppArmor’s @{HOMEDIRS} setting.
I think GP misspoke a bit, but the GGP was suggesting to let $HOME point to /home/user, but to put your actual data in /me. That way apps can "make a mess" in /home/user/.dot-files-galore, while your documents and so on are alone in /me/important-file.txt.
GP then was cautioning that this leaves your most important files at the whims of Unix's simplistic user permissions model, unless you also point systemd and/or AppArmor towards /me.
Systemd needs the common parent directory of the home directory of all users on the system, in order to protect all user home directories from services. There is no “the” user.
Systemd wants to provide an option of limiting services from writing, and optionally also from reading, in the home directories of all users. However, there is no reasonable algorithm to discover a single common parent directory which would not also risk encompassing other directories which should not be restricted, so the hardcoded /home is used by the ProtectHome option. If you have home directories somewhere else, but want the same protection by systemd, you will have to use the InaccessiblePaths or ReadOnlyPaths option for all individual system services which you want to restrict in this manner.
I'd say for windows, you'd probably want to define them as well since a lot of ports will use HOME, XDG_* and other non-windowsy environment variables anyhow.
Considered opinion from decades of desktop computer usage:
Trying to use paths to meaningfully separate data by type is a fool's errand and no one will ever get it "right". It is the primary thing UNIX systems got extremely wrong that not only holds them back in the personal desktop space, but through cultural cross pollination has been ruining other desktop OSs too.
Original single-user desktop OSs had the best solution: keep everything related to the application functionality with the application. The application (in AppDir/file with resource fork/whatever form) itself can be wherever the user feels like putting it, and saved documents go wherever the hell the user feels like putting them. The only exception should be cache and temp data, which should go somewhere global.
This has the benefit of being clear and obvious to the user.
The obvious objections:
> but multiuser!
Is a use case that basically doesn't exist in personal desktop space. To the extent it was ever a useful concept it was during a time when a desktop computer was the only way to access the internet and they were too expensive and bulky to justify more than one in a home. Even then, we managed fine without OS level multiuser support.
To the extent that anything like a multiuser desktop exists it is certainly a niche, and therefore we should handle its problems with virtualization, containerization, filesystem overlay hackery, etc.
> but ease of backup!
Depends entirely on what cross section of things you care about backing up. As it is you already have to search dozens of places for including what you want and have rules for excluding what you don't and no standard is ever going to fix that. Applying those same things to the "everything with the application" model is, at worst, not any worse than things already are.
> but if I copy the application, it also copies the config.
That's a decent point, but I would argue this is the obvious thing and also perhaps what is intended. Solution is to have a standardized mechanism of clearing out the config and other state from the application directory, such that it can be done with a right-click context menu. A factory reset of the application if you will.
> but I never use a mouse and only use the GUI as a really fancy tmux
That's fine, nothing about this model makes your life conceptually any harder. Keep all the applications in directories in your PATH. Factory reset of the application can be just as easily done with a command as a context menu entry. You can still put applications in repos and even overengineer a package manager for them if you really want to.
Back in the old days I could delete `.<whatever>` and reset a program to its defaults. Now I have to navigate through `.config` and try to find where stuff is. How is this better?
Android doesn't really do dot files. Or config files that the user can see at all.
(And if you'd like to amend to "the most used desktop OS", this is obviously aimed at unix-likes, but actually Windows does have an equivalent standard and programs targeting that platform really should be following it just like programs targeting unix-likes really should follow this)
Just like it's obvious what OS I meant, it's also obvious that the article's aim is not as narrow as you're trying to paint it, otherwise it wouldn't have a section on Windows. And the Mac section is also weak, so even that is not a good excuse; and Mac also has a standard, and it's best to ignore it if a user sets an XDG env var
Your advice re. Windows is also bad, for example, for a lot of x-platform tools I care more about x-platform consistency and would set the env var to the same ~/.config, e.g., it's much easier to do backup, and I don't care that there is some OS standard (which aren't great to be followed blindly)
But even for non x-platform apps that Windows AppData defaults are a dumping ground for app data (not configs) I don't care about and don't need to backup or anything , so if there is an option to put some configs that are more important in a different folder, that's better
> otherwise it wouldn't have a section on Windows. And the Mac section is also weak
The Windows section stright-up says they don't really know what the situation is over there, and the macOS section says they couldn't find an official recommendation for non-GUI programs.
> Your advice re. Windows is also bad, for example, for a lot of x-platform tools I care more about x-platform consistency and would set the env var to the same ~/.config, e.g., it's much easier to do backup, and I don't care that there is some OS standard (which aren't great to be followed blindly)
If you just want to make your personal stuff do what you expect, then sure, by all means force everything to whatever you like, but that's not good general advice.
> just want to make your personal stuff do what you expect
That's obviously not "just" what I want, so care to come up with an actual reason why moving from the OS dumping ground to a user's custom folder is not a good general advice?
Programs should default to following the platform convention. It's totally fine for a user to decide that they want to stick everything in ~/.config even on Windows, but it's inappropriate for programs to use that as a default.
XDG specs are crap. Sure one single ~/.config folder is a very good idea. But I want it clearly visible such as ~/config. But I don't want an additional and confusing ~/.local.
Plus I don't want ~/Videos or ~/Pictures folders. I am not dumb. Let me organize my folders according to my needs and my will.
The first thing I do when I setup a user account is removing those useless XDG folders.
XDG pretend to remove folder clusterfuck then why do they add their crappy folders?
Note that XDG_DESKTOP_DIR and XDG_DOWNLOAD_DIR have to point to different directories. In hindsight, this is obvious, but this is also a really stupid "security" bug-o-feature that costed countless hours to countless people.
> Note that XDG_DESKTOP_DIR and XDG_DOWNLOAD_DIR have to point to different directories. In hindsight, this is obvious, but this is also a really stupid "security" bug-o-feature that costed countless hours to countless people.
It's not obvious at all. The only security issue is programs dumping "downloads" on your harddrive without asking you first. Sucks that this is yet another thing that Mozilla has copied from Chrome without thinking.
I'll take the other side of this. We have this concept of applications being "well behaved" if they only read and write from parts of the filesystem that users expect. The XDG directories are what most linux and macOS users expect, even if they don't know about the standard. This well-behavedness feeds into the larger idea of high quality software. Hiqh quality means users are more likely to recommend it, engineers are more likely to respect the application's authors, etc.
The problem with this is that it's all socially enforced, but it's not a social problem, it's a technical problem. The issue isn't that we haven't put enough pressure on developers to read the correct environment variables. It's that we have such a poor isolation story on UNIX that we have to care about where applications read and write from, rather than letting them do whatever they want in a sandbox.
Many of the open source docker images are on the right track here. Where does the persistent state go? /data. Where does the configuration go? /config. Where does the cached data go? /cache. All in the most obvious places right at the filesystem root. Those applications would be considered "badly behaved" outside the container, but inside, it's much easier to predict what they will do.
You can't technically enforce an application to cleanly split cache and configuration data and you will probably already fail to enforce splitting application data and user data for applications that need to access user data.
Technical enforcement is also not free - it has both a performance and usability cost at applies to everyone not just bad actors. One of the things I like about free software is that it allows for high trust environments because you don't need technical restrictions but can instead rely on people not being dicks. I consider this similar to wanting to live in places where I don't have to worry about locking my doors and closing all windows every time I go to the store.
Exactly. It feels foolish to demand N unrelated applications implement support for the same arbitrary ruleset N different times.
Why must applications incorporate implementation details of the deployment environment? Why does the environment owner not have tooling to control where files are placed?
But they don't seem to care https://github.com/rust-lang/cargo/issues/1734 https://github.com/rust-lang/rfcs/pull/1615 https://github.com/rust-lang/cargo/pull/9178