150 comments

[ 5.2 ms ] story [ 128 ms ] thread
Why not `.config`?
Let’s just assume for now that there could be use cases that aren’t strictly config data.
I do think .etc would be a pleasantly smart way to blend with the rest of the world as it exists.

This case isn't covered by XDG, but there's a path here we probably could & should adapt, that suggests itself. And this forges off in a new direction.

https://specifications.freedesktop.org/basedir-spec/basedir-...

We already have the ~/.local (standard? convention?) which simply mimics the filesystem root with bin,etc,include etc.

If we're tossing this into random subfolders, I'm not sure why we wouldn't keep that going?

> ~/.local (standard? convention?) which simply mimics the filesystem root with bin,etc,include etc.

That's not the filesystem root, is it? From what I can tell, ~/.local mimics `/usr`; it has bin and include, yes, but also `share`, and no `/etc` that I'm aware of. `/` does have `bin`, but I don't think I've ever seen `include` there on a system before.

`/usr` can have `/etc` - and my current .local has an `etc` directory directory in it (apparently used by jupyter).
Fair enough, but I think that's even more evidence that `.local` doesn't actually mimic the filesystem root, but `/usr`
I like the idea of a .local!

It's a little weird because presumably repos shouldn't just be a .local folder. We'd still be excepting the actual source from this.

Maybe we just use a FileSystem Heirarchy pattern for repos? Many projects already have source in src/. Move all the build config stuff into a etc/ in the project, no .anything/?

The XDG standard covers most of these as well. Cached data that is safe to delete? There is a directory for that. Runtime data that needs to live as long as the instance of the app? Directory for that. External data your app might rely on but contains no user data? Directory for that.

It's very flexible and widely accepted. It's just not accepted _enough_ to be annoying.

At least a couple of them are unambiguously programs (despite being defined in config formats). And many of the others are configs which allow program formats, which could hypothetically do arbitrary program things as well.

There are other top level files which I’d want to include if I were the one designing this, many of which are just text/reference, all of which are inherently meta content relative to their containing project. It may well even be worth nesting sub-category directories below .meta, eg .meta/config or even .meta/config/{checks,env,…}. I’m sure some would consider any/all of this overkill, but the current status quo of top-level junk is certainly no better than a tree with well defined and well named branches.

".config" seems like such a natural name for it that I assumed it must be taken by some other program so they couldn't use it. I would expect a ".meta" folder to hold things like release history, a graph of the number of files in the project over time, links to external design documents, and other facts "about" the project. Not config files used by the project.
It kind of is... There is a formal standard that everyone ignores called XDG which defines the ".config" directory along with a few other handy common ones.
The XDG base directory specification defines a .config directory for user-specific configuration files (e.g. tmux.conf, i3's config file, a global gitignore file). This proposed standard would be for project-specific configuration files (e.g. a project-local .gitignore, .dir-locals.el, .mypy.ini).
It sucks so bad that so much nonsense auxiliary machinery gets front row billing.

For a while I was dumping stuff into .config but I eventually tired of struggling even more with various tool chains.

IMO this should be more aggressive in a few ways, not the least being it should invert the fallback logic. It should also include some obvious non-config meta-stuff, ie every top level Markdown/plain text file save maybe README.

Lastly, I think part of the reason this problem is so annoying to warrant it is that lots of tools think they’re so special that they need to create a new config even when they create redundancies with other overlapping config content. I know this is a “there are N competing standards” proclamation, but it would be nice if same-ecosystem tools were encouraged to collaborate on config specs/schemas so a great deal more stuff could be defined once, in one format, at one well-known path.

> It should also include some obvious non-config meta-stuff, ie every top level Markdown/plain text file save maybe README.

The problem you're trying to solve with this is just related to the fact that README starts with R. In the past, I've been an advocate for breaking with tradition and naming your README "ABOUT" instead.

> it would be nice if same-ecosystem tools were encouraged to collaborate on config specs/schemas so a great deal more stuff could be defined once, in one format, at one well-known path

Or better: thinking long and hard about the question "What problem is this trying to solve?" and then considering whether another tool that dumps/reads a config file at a fixed location is the best way to deal with it in the first place.

This is such a great idea. I kind of hate all the top level clutter in my repos and it seems to get worse every year. Wonderful suggestion. Whether it’s .meta, .config or .etc I don’t really care.
Agreed - and if you wanted to be cute about names you'd go with .files - dotfiles ;)
The name doesn't make sense, those aren't metadata files, they're configuration or application.

I guess I'm also not seeing what the exact problem is. The project root is crowded, yes, now this suggests making a different directory crowded. The messiness is shifted.

Let’s not bikeshed this. The most common use of the meta prefix means “about (this category)”, eg metadata, but that’s not its only form.

The original Greek prefix is a preposition that means “with”, “among”, or “beside”. Doesn’t seem like a stretch that config files are a type of metafile.

I also had the same reaction. It just doesn't seem very descriptive.

Even .config would be better

The argument that it just moves the clutter to another directory still applies.
I don't understand how that is an argument. Of course organizing things involves moving them to other places. That is basically the definition of organizing something.
It's a bit like cleaning your room by shoving everything into the closet.
So, still better than no tidying?
By that logic, why put any files in directories? Let's keep the entire project at the root level.

The truth is, it's not that the current project roots are a mess. It's that there's a complete and holistic category of file that is being kept in the root of projects, and putting them in a directory dedicated to that category is utterly sensible. Every other category is kept in a dedicated namespace in the file structure, why should config files be the exception?

Or cleaning your room by hanging things up in the closet?
That's literally the point of having a closet.
It's more like cleaning your desk by putting related files into a folder.
The purpose of the closet is to store your things. If your closet is a mess, that's a problem, but it's a better problem than the one you had before.
But that’s still better than not moving the clutter at all. A root directory with important files + clutter is worse then a root directly with only important files and a separate directory with clutter.

I agree with the GP about bikeshedding. A debate about this would never end.

(comment deleted)
> A debate about this would never end.

Which is why the whole thing needs to be nipped in the bud.

For one thing .meta would already be a dotfile so .dotfile/.env would be redundant. But that's called dotenv! What's it going to be named now? Or maybe that wouldn't be included. But it's on the list in the tweet linked to in the article.

> Let's not bikeshed this

Tell this to the guy who started it by suggesting files should be moved in the first place.

Right now any codebase can put them wherever it wants. If you suggest to standardize things you damn better get the whole idea including naming right.

It's a suggestion, not a mandate. Don't adopt it if you don't like it. Geez
If it's a suggestion then why do you care if people suggest something else in return?
This entire thing already feels like a bike shedding exercise. I agree it’s kind of uncomfortable. But I’ve had no real problems over the years of having these files in whatever directory they need to be in given the context they work for.
(comment deleted)
To throw my 2 cents into the hat:

.project - Since these files typically "configure a project", a dot project directory could hold all of those files.

.meta - Agree its not super descriptive, which is fine, but more precision could be good.

.config - Problem with this is "configuration for what?", the project or the application?

.project is out because of how it would interact with Eclipse and derived tools, which used the name first.
A separate directory being crowded with things that serve a similar purpose is vastly superior to dumping crap in the project root, though...

There's a reason Linux doesn't just stuff everything into /

The messiness is shifted but I don't have to see them in the top-level in VSCode. That's a big improvement.
Why is it a problem to see them?
Personal preference. And clearly, from this thread, that's a common reason why.
That sounds like a case for configurable masking at the editor level, rather than for a new standard of project arrangement in the filesystem.
Back in the day, this is what /etc was for. You'd install binaries in /usr or /bin and then NFS mount those from your clients. Then all the config was local in /etc (and the programs generally respected the idea of either creating a config file in /etc on first run or just doing the default thing if it wasn't there).

I'm sad that we got away from that standard. It was nice when I could just back up /etc and be good to go.

(Of course this is looking with rose colored glasses, we never had 100% adherence to the standard, which is how we got to where we are).

You seem to be thinking of programs, this is talking about projects. Various compilers, linkers, CI tools, etc. look in the root directory of your project for config files or other rules. This proposes to move all those files to `.meta` in order to keep the project root directory clean.
Most of the examples they give - like package.json - are specific to the project, not the whole operating system. And they are typically checked in to a project’s git directory.

/etc stores system configuration (like the local timezone). They have a very different purpose.

/etc/nginx and /etc/httpd are two examples that are prevalent but have nothing to do with a system's configuration.
Depends where you think the boundary of "the system" is.
That's incorrect, those are system config (i.e. how nginx/httpd run on your system). Which is a very different type of config than being discussed here.
maybe .self is better
I kinda like the status quo. I like seeing all the tooling artifacts at the top level when I open a GitHub repo or something, it’s nice to see at a glance - like a quick digest of what is used to develop that software. And they all are hidden automatically in a local file browser, so it’s not like it’s really a mess. And the .prefix means they don’t mess up tab completion.

It’s the ones that arent hidden that are a problem, and if they’re already obnoxious enough to choose a non-hidden file name they’re probably not going to support a hidden directory either - Dockerfile, Jenkinsfile, and bitbucket-compose.yml, I’m looking at you.

I tend to agree. The reason these files land in the root directory of many repos is because the multitude of tools that use them expect their file to be in $PWD, and running make or mvn or docker or npm from the root of the repo is usually convenient. Changing that paradigm needs more of a justification than tidiness, I think.
While I wouldn't put Dockerfile and .rc files in the same category, the hardcoded file convention bugs me.

But, can't pretty much any of these be put wherever one wishes? Like `ops/` or w/e?

(comment deleted)
For most of these repo-specific config, if you put it in a subdirectory then some tooling won't work properly. If your dockerfile is in ops/, the you have to tell people how to run docker build. If your .eslintrc is in ops/, then those rules will only apply to files in subdirectories of ops/...
i know this goes down the rabbit hole, but i think every project benefits from a makefile or other taskrunner file. even if a project is a simple “docker build ...” having done task makes it really easy to see
"or other taskrunner file" is the problem, because to some approximation npm or docker are task runners.

The presence of a makefile at the top level tells you you can run make. The presence of a dockerfile tells you you can build with docker. It's not a good system, but it kinda works.

no, a makefile with a docker build task acts as a reference for how to build the image. that’s my point.

_any_ repo has clues about the toolchain encoded in the file types and extensions, but that’s not the same thing.

and yes, npm or yarn can define scripts which can have the same documentation benefits. but there’s lots of others too that are specifically for tasks. i really like https://taskfile.dev.

these files can communicate how to work in a project.

Yeah it's certainly tradeoff, especially for the rc-type files that get auto-detected by editors.

Still, I feel like the status quo is pretty good. Most ecosystems have built in task runners for specifying/documenting commands, js and python projects can opt to shove a lot of config in package.json or pyproject.toml for a lot of ecosystem tooling respectively if they want (similar for a lot of languages).

I wouldn't mind if some ~/.config-like (https://unix.stackexchange.com/a/33945/203864) convention emerged here similar to the .meta proposal though.

Dockerfiles should support that
> I like seeing all the tooling artifacts at the top level when I open a GitHub repo or something, it’s nice to see at a glance - like a quick digest of what is used to develop that software.

I agree with this proposal that it can be a mess, but hiding the files or directories isn’t a solution. Instead, the mess we often see reflects the abysmal unification of tooling in modern software development, and the JS ecosystem is perhaps the worst offender.

If things suck, let them fester in the open air. Stuffing them away isn’t gonna fix the mess, just sweep it under the rug.

I must say though, that one huge pet peeve that I have, is software that don’t allow projects to be rooted in a subdir of the git repo root. This is a huge annoyance when you work with multiple stacks in the same project.

Alright, so what's the solution, and how do we get there?
How is this not a very, very, on-the-nose example of "sweeping the dust under the rug"
Because the most important part of the problem isn't the profusion of config files, it's that as a project owner I'm not in control of the most important entry point to my own work.
The alternative for a lot of things is the root directory having almost nothing in it, because the main content is already split from the top level directory by:

- node monorepos by putting everything in the packages directory

- python repos by putting almost everything underneath the name of the package

What might help some who are annoyed by this perceived clutter is to be to jump straight into the main content in the subdirectory. Getting the other files moved out only helps it a little because you don't have to go through as many items to click or cd into the main content's directory. It doesn't remove a whole step. The steps are still 1) to go to the repo and 2) click or cd to the directory that has the main content.

More like putting utensils into a drawer, as far as I can see.
That's at least some sort of organization (which drawer?), this just hides the mess with no organization.

If you're gonna propose tidying it up, at least propose a useful organization other than just hiding it, like from the example list of files maybe something like 3 subdirectories: installers, linters, and compilers/runners?

Well, presumably the root directory of a code repo does contains drawers (directories) other than ".meta/", e.g. sources in "src/", headers in "include/", assets in "assets/", etc.

I think the point of ".meta" is the drawer for config files of _tools_. And these tools, depending on the language and the ecosystem, might not fall into neat subdirectories like "installers", or "linters". Some compiler comes with their own packaging system, and some with their own linter.

".meta/{tool_name}.{ext}" or ".meta/{tool_name}/*.{ext}" should be sufficient in that regard. (Though I do prefer ".config" over ".meta")

In my closet there is a bin full of batteries. This bin has no internal organization; all different types of batteries are jumbled together. You could say that I have just hidden the mess, and that there is no point having a battery bin unless you are also going to have a sub-bin for each type of battery - but in practice, this is enough. When I need a battery, I know where to look for it, and there are no batteries cluttering up any other parts of my house.
I’ve had a similar idea in my mental “this would be a cool convention” list: .dotfiles/ or .dots/ , strictly for getting dotfiles out of the root dir.

The criteria is a little clearer compared to “config” files, which could mean a lot of things.

Would this also apply to home directory, eg ~/.meta/.netrc? That would be neat and make backing up a system and synching configs easier.

Also, what about .idea/.vscode and related IDE stuff? Those I would definitely consider "metadata".

Would X/.meta/.dockerignore work the same as X/.dockerignore ? As in relative to the root as if .meta was not there?

Not sure I agree with docker-compose.yml being there, but not really opposed to it either. What about Makefile or CMakeList.txt?

> Would this also apply to home directory, eg ~/.meta/.netrc? That would be neat and make backing up a system and synching configs easier.

~/.config and ~/.local already exist for that purpose: applications should read and store configuration in ~/.config, use ~/.local/share for data, and install binaries to ~/.local/bin.

for home directories .config, .local and .cache are gaining popularity
I don't think ~/.meta is needed when there's the XDG config path, which by default is ~/.config

For unix-like systems like Linux at least, for Windows there is the AppData directory with the same function.

This is such a dejavu, I remember a few years ago someone made the same initiative and succeeded to get a lot of repos/projects to place all their dotfiles in one folder, but I do not remember the name of the folder... anyone?
It'd probably make a lot more sense for it to be called `.config/`, amongst all other things, but for this to gain any traction at all, some bigger projects need to show initiative first. Everything already has like 47 potential config file names they read, so adding another one won't put a dent into the schedule
This has been proposed yearly for a long time. See https://dot-config.github.io/ for one of the latest attempts.

Hiding files under a directory is not really a solution for anything other than slightly improving file navigation, but even if you think it's valuable, the real problem is getting tools to adopt it. There is no incentive to be the first. The intermediate state is terrible - now you need to guess if a config is located at the root or this new config directory, and if your version of the tooling is able to pick up the new location.

I see no reason for this at all.
> This is avoid making a mess in the root directory of projects, as [this] tweet laments.

Registered an entire domain name to back an idea based on a tweet, but completely missing the point of that tweet. If only they'd read the tweeter's own replies under that same tweet they could've avoided wasting their time on this.

For clarity: the original tweeter was bemoaning the state of JS tooling (the busy root directory being a symptom - not the core problem). Throwing your fifty config files in a hidden subdirectory is what's typically referred to as "supporting dysfunction".

> Throwing your fifty config files in a hidden subdirectory is what's typically referred to as "supporting dysfunction".

Hilarious expression. But we’re going even further here: standardizing dysfunction.

The only thing in the root of my projects ARE these files. That’s the whole point of the root in my opinion.
Wouldn't `.configs` make more sense?
The problem is like we all want to do things slightly different but to get mostly the same results.

Prediction: Once we have AI in between everything all these config files will disappear.

https://github.com/bigskysoftware/dotmeta/issues/4

---

While probably a bikeshed consideration, .config is a much more obvious name to use for this.

HN thread with many agreements:

    https://news.ycombinator.com/item?id=36472613
Previous project suggesting .config:

    https://dot-config.github.io/
I'd suggest leaving this issue around and collecting thumbs up / down (Please don't comment with +1s on this, unless you have something novel to add).
(comment deleted)
Instead of attempting to change ALL tools to accept a config file in a non-standard location which is never going to happen, and will just lead to having files in both locations, just recode the file browsers to optionally display config files under a virtual directory. There’s surely fewer file browsers than tools.
This was my thought as well. VS Code already has files.exclude in .vscode/settings.json
Yeah that's what I use when I care enough
This is great! I didn't know about it. What files have you added?
I actually have an extension that adds a little expandable section called "Hidden Files" at the bottom of the explorer pane, where I can open it and add a check beside the files I want to hide. In some projects, I change it at leisure, which usually means I'm hiding any files that never have any bearing on my day to day work. Sorry I don't remember the exact name of the extension.
I'd suggest having them in a directory just called config/

On having it start with a dot: Why? Why would we pretend that these crucial files don't exist?

On having it named meta: These files aren't "about" the project or "above" the project, they ARE the project.

Yeah hiding these files would be a huge mistake.
and security problem. whoops, just committed all the secrets in .meta/.env.production!
Thank god when you commit, the editor lists all the files you've committed in the comments of the commit message.
What editor? There's no editor in git add . && git commit -am "made changes" /s
hooo boy. i could feel my blood pressure spike for a brief moment before i saw the `/s`.
Yes, but why would anyone follow this very reasonable line of thinking if you don't have a custom domain name to back it up?
Or hide them with your IDE if they disturb you so much
~/.config is already a thing
(comment deleted)
It's not configuration though. Specifically, it's not configuration of the project in question, it's configuration for third party accessories.

If I'm writing an editor, I expect the config directory in the source code to hold the configuration for the editor, not .babelrc

meta is a much better name and they are "about" the project, not the project itself, so I disagree on that point. Though I agree it should not be hidden. I will start having a "meta" directory in my projects

But third party accessories are an essential part of any project these days, they aren't optional or afterthoughts. In that page they mention docker-compose.yml as once example. Most likely it's impossible (in its current state) to actually run that application without Docker.

Other things that would land in the folder:

- Files essential to building the project - Files essential to running the test suite - Files essential to developing on the project

IMO a "project" includes all those things. In your definition are those all "meta"? Does "meta" mean anything that's not source code?